|
4289
|
154
|
17
|
2026-05-07T13:23:50.328964+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160230328_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] DEBUG Getting headers', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch ...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"bounds":{"left":0.33976063,"top":0.09736632,"width":0.66023934,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3394282,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] DEBUG Getting headers', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] DEBUG Getting headers', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7753210734642263226
|
6593672105841920124
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] DEBUG Getting headers', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch ...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4288
|
154
|
16
|
2026-05-07T13:23:40.856480+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160220856_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] DEBUG to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to ...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"bounds":{"left":0.33976063,"top":0.09736632,"width":0.66023934,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3394282,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] DEBUG to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] DEBUG to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4169697535611246908
|
6593672105841920124
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] DEBUG to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to ...
|
4287
|
NULL
|
NULL
|
NULL
|
|
4287
|
154
|
15
|
2026-05-07T13:23:37.685830+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160217685_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to ...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"bounds":{"left":0.33976063,"top":0.09736632,"width":0.66023934,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.3394282,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
4668056249539755827
|
6611686504351402108
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to ...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4286
|
154
|
14
|
2026-05-07T13:23:33.426800+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160213426_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fe...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"bounds":{"left":0.33976063,"top":0.09736632,"width":0.66023934,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
2568182829538570492
|
6593672105841920124
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fe...
|
4283
|
NULL
|
NULL
|
NULL
|
|
4285
|
153
|
14
|
2026-05-07T13:23:33.354159+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160213354_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fe...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
2568182829538570492
|
6593672105841920124
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fe...
|
4284
|
NULL
|
NULL
|
NULL
|
|
4284
|
153
|
13
|
2026-05-07T13:23:24.424074+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160204424_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray()...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-1835529063972877357
|
6593672105841920124
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray()...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4283
|
154
|
13
|
2026-05-07T13:23:24.423989+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160204423_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray()...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"bounds":{"left":0.33976063,"top":0.09736632,"width":0.66023934,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-1835529063972877357
|
6593672105841920124
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray()...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4282
|
153
|
12
|
2026-05-07T13:23:11.727778+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160191727_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
475221511721291612
|
-2734443048106031937
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4280
|
NULL
|
NULL
|
NULL
|
|
4281
|
154
|
12
|
2026-05-07T13:23:11.650531+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160191650_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"195","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","depth":4,"bounds":{"left":0.33976063,"top":0.09736632,"width":0.66023934,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"934766d6-40c0-415c-bd51-d0b67a799c7c\",\"trace_id\":\"d6c773e8-adf4-453b-8a17-077bf7bdf698\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b99dafc3-0e7f-4cb3-9469-9a18bd4d8a72\",\"trace_id\":\"3ca2e911-32f2-4c22-89ba-aae5e8342c8d\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:20:00, 2026-05-07 13:22:00] {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:41] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b8b1efaa-e359-4aa1-942d-2dc8ca6c048b\",\"trace_id\":\"897fc576-4657-4534-ac78-73f6c44cbeef\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"08dc0025-4642-4d21-a351-c0dee099d6fc\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:52] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"13eed139-b218-43c9-b147-38ae92c45977\",\"trace_id\":\"b0e009f0-3c67-4281-87ce-4ccdc1ab3055\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf9df816-4614-4a06-b853-4d6815fb85e1\",\"trace_id\":\"ca6ed313-c21f-4683-8b5b-013a3ecd4081\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:22:57] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"twilio:recover-tracks\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"93d3bd4f-fe02-4d22-aab9-00c74309e94c\",\"trace_id\":\"356db0f7-0c25-4739-8c8b-a55ba28e1df0\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"connect-and-sell\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Start user synchronisation {\"provider\":\"justcall\",\"teams_count\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Synchronising team {\"provider\":\"justcall\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf9285a-8ded-4a8b-bd7d-ec68c398f2f9\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1367,\"sociable_id\":1071,\"provider_user_id\":\"005O4000003s5c7IAA\",\"expires\":null,\"refresh_token_expires\":null,\"provider\":\"salesforce\",\"state\":\"full-refresh\",\"auth_scope\":\"refresh_token web api\",\"retry_after\":null,\"created_at\":\"2024-09-10 07:05:21\",\"updated_at\":\"2026-01-14 07:00:58\"}}} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":1071,\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.WARNING: Failed to sync external users {\"message\":\"Your Salesforce account has become disconnected. Please login to Jiminny to reconnect.\",\"provider\":\"justcall\",\"team_id\":1,\"team\":\"jiminny\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"ringcentral\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"avaya\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"telus\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"salesloft\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"talkdesk\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Skip provider synchronisation, no teams found {\"provider\":\"vonage\"} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Done {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}\n[2026-05-07 13:23:00] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:sync-users\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb2297ef-3768-4c39-a39d-8d56cc5f19fd\",\"trace_id\":\"f5f44e82-383e-4e36-b898-5e6a6bb73621\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
475221511721291612
|
-2734443048106031937
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
195
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4279
|
NULL
|
NULL
|
NULL
|
|
4280
|
153
|
11
|
2026-05-07T13:23:08.329151+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160188329_m1.jpg...
|
PhpStorm
|
faVsco.js – custom.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
18
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Pagination;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Services\Crm\Hubspot\Client;
use Jiminny\Services\Crm\Hubspot\PayloadBuilder;
use Psr\Log\LoggerInterface;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
class HubspotPaginationService
{
public function __construct(
private LoggerInterface $logger
) {
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Editor for custom.log","depth":4,"on_screen":true,"role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7414464124730059060
|
-6616387587077397585
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
18
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Pagination;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Services\Crm\Hubspot\Client;
use Jiminny\Services\Crm\Hubspot\PayloadBuilder;
use Psr\Log\LoggerInterface;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
class HubspotPaginationService
{
public function __construct(
private LoggerInterface $logger
) {
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4279
|
154
|
11
|
2026-05-07T13:23:08.327894+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160188327_m2.jpg...
|
PhpStorm
|
faVsco.js – custom.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
18
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Pagination;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Services\Crm\Hubspot\Client;
use Jiminny\Services\Crm\Hubspot\PayloadBuilder;
use Psr\Log\LoggerInterface;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
class HubspotPaginationService
{
public function __construct(
private LoggerInterface $logger
) {
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Editor for custom.log","depth":4,"bounds":{"left":0.41422874,"top":0.09736632,"width":0.2975399,"height":0.8818835},"on_screen":true,"role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7414464124730059060
|
-6616387587077397585
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
18
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot\Pagination;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Services\Crm\Hubspot\Client;
use Jiminny\Services\Crm\Hubspot\PayloadBuilder;
use Psr\Log\LoggerInterface;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
class HubspotPaginationService
{
public function __construct(
private LoggerInterface $logger
) {
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4278
|
153
|
10
|
2026-05-07T13:22:50.357207+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160170357_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"153","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7010092711957264102
|
-9032716130787655505
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4276
|
NULL
|
NULL
|
NULL
|
|
4277
|
154
|
10
|
2026-05-07T13:22:50.264681+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160170264_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"153","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"bounds":{"left":0.4168883,"top":0.09736632,"width":0.5831117,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7010092711957264102
|
-9032716130787655505
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4275
|
NULL
|
NULL
|
NULL
|
|
4276
|
153
|
9
|
2026-05-07T13:22:43.758418+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160163758_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
Sync Changes
Hide This Notification...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"153","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_selected":false,"is_expanded":false}]...
|
-178655497226894629
|
-2615104666308507477
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
Sync Changes
Hide This Notification...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4275
|
154
|
9
|
2026-05-07T13:22:43.700674+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160163700_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"153","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"bounds":{"left":0.4168883,"top":0.09736632,"width":0.5831117,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7723552493048502633
|
-2615104666303790941
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4274
|
154
|
8
|
2026-05-07T13:22:42.218848+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160162218_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
Sync Changes
Hide This Notification
Code changed:
Hide
18
1
Previous Highlighted Error
Next Highlighted Error...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"153","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"bounds":{"left":0.4168883,"top":0.09736632,"width":0.5831117,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-534142117299244992
|
-2615104666303788885
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
Sync Changes
Hide This Notification
Code changed:
Hide
18
1
Previous Highlighted Error
Next Highlighted Error...
|
4272
|
NULL
|
NULL
|
NULL
|
|
4273
|
153
|
8
|
2026-05-07T13:22:35.587723+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160155587_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7429716278976468786
|
-8636355650190325311
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
iTerm2ShellEditViewSessionScriptsProfilesWindowHelplabl• Lukas/Stefka 121 • in 1h 8 m100% <478Thu 7 May 16:22:35DEV (docker)APP (-zsh)*3T81DOCKERO ₴1DEV (docker)182worker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugMatching contact 0Matching contact 1Matching contact 2Matching contactMatchingcontact4Matchingcontact5Matchingcontact 6Matching contact 7Matching contact 8Matching contact 9root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugMatching contact 0-zsh• 84|screenpipe*•$5Jiminny \Exceptions \RateLimitExceptionHubspot returned 429at app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206202'retry_after' =SretryAfter,203"reason"204= Se->getMessage(),205→ 206throw new RateLimitException('Hubspot returned 429', SretryAfter, $e);207208} else 1throw $e;209}210+14 vendor frames15-zsh₴6DEVapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:166SevenShores\Hubspot\Http\Client:: request("POST", "[URL_WITH_CREDENTIALS] ]...
|
4270
|
NULL
|
NULL
|
NULL
|
|
4272
|
154
|
7
|
2026-05-07T13:22:35.587718+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160155587_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7429716278976468786
|
-8636355650190325311
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
PhostormVIeWINavigareCodeLaravelKeractorFV faVsco.js°9 master kProiect(C) TranscodeParameterRescl© HubspotPagina(enService.php X© UserService.php© Uuid.php> D Traits> D UseCases> D User> D Utils› D Validation> OvOphp nelpers.ong© InitialFrontendState.php© Jiminny.php© Plan.php© Serializer.php© TeamScimDetails.phpbootstrap>© build.> contia> O contrib.→ database>O docsM front-end>D lang> node_modules library rootM ohostan>D public>O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.onopnp customer_api.onppnp embedded.ongpnp nealtn.onppnp scim.onophp uprotectedweb.phpphp web.phpphp webhook.php>O scriptsv O storage>M debugbarM frameworkv Mloas.aitianoreê audio. wav= custom.loalJiminnyDedugcommano.phpD IntegrationApp/.../SyncCrmEntitiesTrait.phpT OpportunitySyncTrait.phpC) Hubspotsinglesyncstrategy.php© WebhookSyncBatchProcessor.phcImportbatchJoblrait.ono(C) Hubspot/Service.pho© Companies.php(C) MatchActivityermData.pho(C) CrmActivityService.php(C) CachedCrmServiceDecorator.php* Hubspot/.../SyncCrmEntitiesTrait.php©) Pipedrive/Service.php0 Servicelntertace.php@' OpportunitvSvncTest.ohp© RateLimit.phpC) ProviderRateLimiter.ohonespace Jiminny\Services\Crm\Hubspot \Pagination;A18 V1 лe Jiminny\Exceptions RateLimitException;? Jiminny services urm Hubspoc Lulench¿ Jiminny services crm Hubspot Payloadbullder:202 Psr Loa Loggerintertace:sevenshores hubspor xceptions badkequest• Jaminny Exceptions SocialAccountTokeninval1dExceotion:ass HubspotPaqinat ionServicenublic function constructdprivate Loggerinterface SLogger* @throws HubspotException* Athrows SocialAccountTokenInvalidExcentzon* Othrows BadRequestpublic function getPaginatedDataGenerator(cient Sclient,array Spayload,string $typeint Soffset = 0,int &Stotal = 0,?string &$lastRecordId = null): \Generator {sscare = new raqinacionscacelottser. sottsecrSendpoint = Client::BASEURLI"/crm/vs/obnects/Styper/search"SdefaultFilter = Spavload'filters'i??USresultsPerPage = PavloadBuilder::MAX SEARCH_REQUEST_LIMIT:Steamid = Scllent->qetconfiq0->getteamo->getdo:Sdelav = Sthis->calculateDelavInMicroseconds@:do ≤us tht isif (Sthis->shouldStonPaqination(Sstate. Steamld)) {= hubspot-journal-poll.log= laravel log1I1ISpayload = $this->handlePaginationStrategy(Spayload, $defaultFilter, $state, SresultsPerPage, $tnarAube for lblE suadestiionsa Detect more seawritvlsaues lin vour D.D files llia SonarAube Claud for free //lDownload SonarOnbe Server lllearn more //lDonit ask again /(today 105251=custom.log4 HS_local [jiminny@localhostiti accounts (jiminny@localhost]A console (PROD)A console [STAGING]W153 A V[2026-05-07 13:22:12] local.INF0:[SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubsp[2026-05-07 13:22:12] local.INFO:[2026-05-07 13:22:12] local.INF0:LsoclaLAccouncservice. loken neeas rerreshing i soclaLAccounclo.14%% "provlde[EncryptedTokenManager] Generating access token. {"mode":"leqacy"} {"correlatio.2026-05-07 15:22:12 Local.INFU: Soc1aLAccountServicel Retreshing token trom provider •"soc1aLAccoUntId":1499."1[2026-05-07 13:22:12] local.INF0:12026-05-07 15:22:12 Local.INF0:Soc1aLAccountUbserver Access token was modified, encryoting -"correlation1d[2026-05-07 13:22:13] local.INF0:ntId":1499, "provider": "hub12026-05-07 13:22:13 Local.INF0:CrmownerResolver Integration owner matched as CRM Owner -"crm provider":"hubsi12026-05-07 15:22115 Loc0LJNFO:[Hubspot) Received 429 from APL 1"team_1d":2, "conf1g_1d":2,"retry_after":10,"rCustarus*lercormessade"*"You have ceached vour secondy lama"ennocmelACRAF DCOnne"} {"correlation_id": "343f341d-028f-4C8c-9578-252fcde6e04c", "trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}-12026-05-07 13:22:13 Local, ERROR: Hubsoot returned 429 "excention""obiect]lNiminny Excentions RateLimitexcstacktrace]l#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\Services\\Crm\\Hu,#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot|\Pagination\\HubspotPaç#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny(Services\\Crm\\Hubspot\\Client->getPaginatec#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny||Services|\Crm\\Hubspot\\Service->matc#4/home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommane#5/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Command:#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethe#7/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Uti#8/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\Bo#9/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\Bour#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminatel\Container\\Contair#11/home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\Consolel\Command->execute(Obiect(S)#12/home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony|Component\Consolel\C#13/home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\Console\Command->run(Obiect(Symfony)\#14/home/jiminny/vendor/symfony/console/Application.php(356): Symfony|\Component\Console\Application->doRunComi#15/home/jiminny/vendor/symfony/console/Application.php(195): Symfony|\Component\Console\Application->doRun(Obi#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfonyl\Component\V#17/home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.pho(1235): Illuminatel\Foundatior#18 /home/jiminnv/artisan(13): Illuminatel\Foundation!\Application->handleCommand(Obiect(Svmfonv|\Componentl\Consc#19 <main?orevious excention obiect (SevenShoresHubsootExcentions BadRequest(code: 429): Client error: "POSt httos:{\"status\":\"error\", \"message\":\"You have reached your secondly limit.\", \"errorType\":\"RATE_LIMIT\", \"correlat/home/iiminny/vendor/hubsoot/hubsoot-oho/src/Exceotions/HubspotExceotion.ono:2401listacktnace#0/home/iiminnv/vendor/hubsnot/hubsnot-nhn/src/Httn/Client.nhn(125)• SevenShoresHubsnotExcentionsHubsnotExc#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http#2/home/iminnv/ann/Services/Crm/Huhsnot/Pagination/HubsnotPaginationSenvice.nhn/52)• JiminnvServicesCrmHut:/home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny|\Services\\Crm\\Hubspot\\Pagination\\HubspotPac#//home/iiminnv/ann/Services/Crm/Huhsnot/Service.nhn(1203)• liminnv ServicesCrm.Huhsnot Client->ae+Paginater:/home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\|Services\\Crm\\Hubspot\\Service->mat#6/home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommane#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny|\Consolel\Command:#8/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\ContainerBoundMeth#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminatel|Container|lUti#10/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BcLukas sterka 121• In ih om100% 12Inu / May 10.22:30AskJiminnyReportActivityServiceTest -CascadeHubspot Rate LimitingHubspot Rate Limit H+0 ..How to Access the Header in Your codeIf you need to check the header manually for debugging:• php// For new SDK (ApiException)trySresponse = Sclient->request...:} catch (\HubSpot\Client\Crm\Objects\ApiException $e) {nseHeaders() ?: 01;SretryAfter = $headers ('Retry-After'][0] ?? $headers['retry-after'] [0] ?? null;f(SretrvAfter)// HubSpot sent retry guidance} else{/ No header - use detault based on error messageShody = ison decode(Se-saetResponseBodvo). true):SretryAfter = match($body['policyName'] ?? null) {detault = 10,RecommendationThe current imolementation at Service.oho: 1721-1727 already handles this correctly by checking policyname:• ph:sresponse =son decodelse->geckesponsebody, truenisset(Sresponse['policyName'))&& Sresponsel'policyName'] == self::TEN SECONDLY ROLLING POLICY?self::TEN SECONDLY ROLLING LIMITI: 1; // Default 1 second for other limitsI/ 10 seconds|To see if headers are actually present, add temporary logging:phoSheaders = se->oetResponseHeaderso?::Log: : debug('[HubSpot) Rate limit response headers', [headers = Sheaders'retry_after' => $headers ['Retry-After'] ?? $headers['retry-after'] ?? 'NOT_PRESENT',Ask anvthina (&4D)C° AdantiveWN Windsurf Teamc2-1UTE.8io 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4271
|
154
|
6
|
2026-05-07T13:22:27.283531+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160147283_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"153","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"bounds":{"left":0.4168883,"top":0.09736632,"width":0.5831117,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
-7723552493048502633
|
-2615104666303790941
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}...
|
4269
|
NULL
|
NULL
|
NULL
|
|
4270
|
153
|
7
|
2026-05-07T13:22:24.601003+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160144601_m1.jpg...
|
PhpStorm
|
faVsco.js – custom.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Editor for custom.log","depth":4,"on_screen":true,"role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
61097548596911936
|
-8132287983061464126
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
iTerm2ShellEditViewSessionScriptsProfilesWindowHelplabl• Lukas/Stefka 121 • in 1h 8 m100% <478Thu 7 May 16:22:25DEV (docker)APP (-zsh)*3T81DOCKERO ₴1DEV (docker)182worker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugMatching contact 0Matching contact 1Matching contact 2Matching contactMatchingcontact4Matchingcontact5Matchingcontact 6Matching contact 7Matching contact 8Matching contact 9root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugMatching contact 0-zsh• 84|screenpipe*•$5Jiminny \Exceptions \RateLimitExceptionHubspot returned 429at app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206202'retry_after' =SretryAfter,203"reason"204= Se->getMessage(),205→ 206throw new RateLimitException('Hubspot returned 429', SretryAfter, $e);207208} else 1throw $e;209}210+14 vendor frames15-zsh₴6DEVapp/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:166SevenShores\Hubspot\Http\Client:: request("POST", "[URL_WITH_CREDENTIALS] ]...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4269
|
154
|
5
|
2026-05-07T13:22:22.922801+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160142922_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"153","depth":4,"bounds":{"left":0.6838431,"top":0.10055866,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"bounds":{"left":0.4168883,"top":0.09736632,"width":0.5831117,"height":0.90263367},"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n\n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7010092711957264102
|
-9032716130787655505
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
153
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST [URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4268
|
153
|
6
|
2026-05-07T13:22:22.831384+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160142831_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {\"team_id\":2,\"config_id\":2,\"retry_after\":10,\"reason\":\"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {\"exception\":\"[object] (Jiminny\\\\Exceptions\\\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\n[previous exception] [object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#21 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e029a-6 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#31 {main}\n\"} {\"correlation_id\":\"343f341d-028f-4c8c-9578-252fcde6e04c\",\"trace_id\":\"41071c00-9712-46eb-8acf-d5c4298fea69\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c\",\"trace_id\":\"b9aec736-45fd-47fc-9482-fd558ed6227a\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c\",\"trace_id\":\"284e571d-ab92-4e22-b09b-c151c2871cb4\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring start {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}\n[2026-05-07 13:22:19] local.NOTICE: Monitoring end {\"correlation_id\":\"c41d4048-0465-4dcf-bb53-176287732e3e\",\"trace_id\":\"9ce4a71c-a1a0-456e-843d-38fd15e5c798\"}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_expanded":false}]...
|
-4776780067841733158
|
-2615104666287013717
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:12] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: [Hubspot] Received 429 from API {"team_id":2,"config_id":2,"retry_after":10,"reason":"Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.ERROR: Hubspot returned 429 {"exception":"[object] (Jiminny\\Exceptions\\RateLimitException(code: 0): Hubspot returned 429 at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:206)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
[previous exception] [object] (SevenShores\\Hubspot\\Exceptions\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\Hubspot\\Exceptions\\HubspotException::create(Object(GuzzleHttp\\Exception\\ClientException))
#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#4 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#5 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#13 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#21 {main}
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e029a-6 (truncated...)
at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)
[stacktrace]
#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\Exception\\RequestException::create(Object(GuzzleHttp\\Psr7\\Request), Object(GuzzleHttp\\Psr7\\Response), NULL, Array, NULL)
#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\Middleware::GuzzleHttp\\{closure}(Object(GuzzleHttp\\Psr7\\Response))
#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\Promise\\Promise::callHandler(1, Object(GuzzleHttp\\Psr7\\Response), NULL)
#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\Promise\\Promise::GuzzleHttp\\Promise\\{closure}()
#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\Promise\\TaskQueue->run(true)
#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\Promise\\Promise->invokeWaitFn()
#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\Promise\\Promise->waitIfPending()
#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\Promise\\Promise->invokeWaitList()
#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\Promise\\Promise->waitIfPending()
#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\Promise\\Promise->wait()
#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\Client->request('POST', 'https://api.hub...', Array)
#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(166): SevenShores\\Hubspot\\Http\\Client->request('POST', 'https://api.hub...', Array)
#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(52): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), 'https://api.hub...', Array, Object(Jiminny\\Services\\Crm\\Hubspot\\Pagination\\PaginationState))
#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#14 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#15 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#23 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#26 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#31 {main}
"} {"correlation_id":"343f341d-028f-4c8c-9578-252fcde6e04c","trace_id":"41071c00-9712-46eb-8acf-d5c4298fea69"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:13] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"42c3d939-2b42-4fa8-9f57-cbdc5bb1457c","trace_id":"b9aec736-45fd-47fc-9482-fd558ed6227a"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"076c3e6b-6a67-4774-8aa0-2a84fcf5e03c","trace_id":"284e571d-ab92-4e22-b09b-c151c2871cb4"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring start {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}
[2026-05-07 13:22:19] local.NOTICE: Monitoring end {"correlation_id":"c41d4048-0465-4dcf-bb53-176287732e3e","trace_id":"9ce4a71c-a1a0-456e-843d-38fd15e5c798"}...
|
4267
|
NULL
|
NULL
|
NULL
|
|
4258
|
153
|
0
|
2026-05-07T13:21:46.465735+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160106465_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-2796147080355312063
|
-8636637127315567163
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp<DEV (docker)88340(ab)A Lukas/Stefka 121 • in 1h 9m100% CDOCKERO 81DEV (docker)882APP (-zsh)jiminny-worker-processing-4:jiminny-worker-processing-4_00:stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00: stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00:stoppedworker-conferences:worker-conferences_00:stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker:worker_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-crm-sync:worker-crm-sync_00:stoppedworker-emails:worker-emails_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny: debugMatching contact 0Matching contact 1Matching contact 2Matching contactMatchingcontact 4Matchingcontact 5Matching contact 6Matching contact 7Matching contact 8Matching contact 9root@docker_lamp_1:/home/jiminny#-zsh• $4screenpipe*• $5-zshThu 7 May 16:21:46T&1*6+DEV...
|
4255
|
NULL
|
NULL
|
NULL
|
|
4252
|
152
|
22
|
2026-05-07T13:21:15.062140+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160075062_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"39","depth":4,"bounds":{"left":0.68550533,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","depth":4,"bounds":{"left":0.41422874,"top":0.09736632,"width":0.58577126,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n \n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n \n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7869065659943035457
|
-6724494878216116305
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4251
|
151
|
23
|
2026-05-07T13:21:15.149558+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160075149_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"39","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n \n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n \n yield;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7869065659943035457
|
-6724494878216116305
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
yield;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4250
|
152
|
21
|
2026-05-07T13:21:05.469797+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160065469_m2.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"39","depth":4,"bounds":{"left":0.68550533,"top":0.10055866,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.09896249,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.09896249,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","depth":4,"bounds":{"left":0.41422874,"top":0.09736632,"width":0.58577126,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.35073137,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"bounds":{"left":0.3600399,"top":0.2490024,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.37167552,"top":0.2490024,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-2886865811916709792
|
-6864106466664599633
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4248
|
NULL
|
NULL
|
NULL
|
|
4249
|
151
|
22
|
2026-05-07T13:20:50.158437+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160050158_m1.jpg...
|
PhpStorm
|
faVsco.js – HubspotPaginationService.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"39","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"18","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\Pagination;\n\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Services\\Crm\\Hubspot\\Client;\nuse Jiminny\\Services\\Crm\\Hubspot\\PayloadBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\n\nclass HubspotPaginationService\n{\n public function __construct(\n private LoggerInterface $logger\n ) {\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n Client $client,\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n $state = new PaginationState(offset: $offset);\n $endpoint = Client::BASE_URL . \"/crm/v3/objects/{$type}/search\";\n $defaultFilter = $payload['filters'] ?? [];\n $resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;\n $teamId = $client->getConfig()->getTeam()->getId();\n $delay = $this->calculateDelayInMicroseconds();\n\n do {\n// if ($this->shouldStopPagination($state, $teamId)) {\n// break;\n// }\n\n $payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);\n\n// $this->validateTokenIfNeeded($client, $state);\n// usleep($delay);\n\n $page = $this->executeSearchRequest($client, $endpoint, $payload, $state);\n\n// $state->setTotal($page['total'] ?? 0);\n// $this->updateLastRecordId($page, $state);\n//\n// // Safely iterate over results with null check\n// $results = $page['results'] ?? [];\n// foreach ($results as $row) {\n// $state->incrementTotalRecords();\n// yield $row;\n// }\n//\n// $state->setOffset($this->getNextOffset($page));\n// $state->incrementRequestCount();\n//\n// $this->logPaginationProgress($state, $teamId, $endpoint);\n } while ($state->offset && ! empty($page['results']));\n\n // Log final pagination completion stats\n $this->logger->info('[Hubspot] Pagination completed', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'total_requests' => $state->requestCount,\n 'total_records_fetched' => $state->totalRecords,\n 'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),\n 'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,\n ]);\n\n // Update reference parameters\n $total = $state->total;\n $lastRecordId = $state->lastRecordId;\n }\n\n private function shouldStopPagination(PaginationState $state, int $teamId): bool\n {\n if ($state->hasReachedSafetyLimit()) {\n $this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [\n 'team_id' => $teamId,\n 'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,\n 'total_fetched' => $state->totalRecords,\n ]);\n\n return true;\n }\n\n return false;\n }\n\n private function handlePaginationStrategy(\n array $payload,\n array $defaultFilter,\n PaginationState $state,\n int $resultsPerPage,\n int $teamId\n ): array {\n if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {\n $payload['filters'] = $defaultFilter;\n $payload['filters'][] = [\n 'propertyName' => 'hs_object_id',\n 'operator' => 'LT',\n 'value' => $state->lastRecordId,\n ];\n\n $this->logger->info('[Hubspot] Search keyset pagination request', [\n 'team_id' => $teamId,\n 'sequence' => $state->requestCount,\n 'itemsPerPage' => $resultsPerPage,\n 'payload' => $payload,\n 'total' => $state->total,\n ]);\n\n unset($payload['after']);\n $state->setOffset(0);\n }\n\n if ($state->offset) {\n $payload['after'] = $state->offset;\n }\n\n return $payload;\n }\n\n private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool\n {\n // Check if we've hit the offset limit\n $shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;\n\n if ($shouldSwitch && $state->lastRecordId === null) {\n $this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [\n 'request_count' => $state->requestCount,\n 'current_offset' => $state->offset,\n 'results_per_page' => $resultsPerPage,\n 'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,\n ]);\n\n return false; // Continue with offset pagination\n }\n\n return $shouldSwitch;\n }\n\n private function validateTokenIfNeeded(Client $client, PaginationState $state): void\n {\n if ($state->shouldValidateToken()) {\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n }\n }\n\n private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array\n {\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n return $response->toArray();\n } catch (\\Exception $e) {\n if ($client->isUnauthorizedException($e)) {\n $this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n $client->ensureValidToken();\n $state->updateLastTokenCheck();\n\n try {\n $response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);\n\n $this->logger->info('[Hubspot] Token refresh and retry successful', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n ]);\n\n return $response->toArray();\n } catch (\\Exception $retryException) {\n $this->logger->error('[Hubspot] Retry request failed after token refresh', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'original_error' => $e->getMessage(),\n 'retry_error' => $retryException->getMessage(),\n ]);\n\n throw $retryException;\n }\n } else if ($client->isHubspotRateLimit($e)) {\n $retryAfter = $client->parseRetryAfter($e);\n\n $this->logger->info('[Hubspot] Received 429 from API', [\n 'team_id' => $client->getConfig()->getTeam()->getId(),\n 'config_id' => $client->getConfig()->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n } else {\n throw $e;\n }\n }\n }\n\n private function updateLastRecordId(array $page, PaginationState $state): void\n {\n $lastRecord = ! empty($page['results']) ? end($page['results']) : null;\n $lastRecordId = $lastRecord['id'] ?? null;\n $state->updateLastRecordId($lastRecordId);\n }\n\n private function getNextOffset(array $page): int\n {\n return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;\n }\n\n private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void\n {\n if ($state->shouldLogProgress()) {\n $this->logger->info('[Hubspot] Pagination progress log', [\n 'team_id' => $teamId,\n 'endpoint' => $endpoint,\n 'requests_made' => $state->requestCount,\n 'records_fetched' => $state->totalRecords,\n 'elapsed_seconds' => $state->getElapsedSeconds(),\n ]);\n }\n }\n\n private function calculateDelayInMicroseconds(): int\n {\n return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-2886865811916709792
|
-6864106466664599633
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
39
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"[URL_WITH_CREDENTIALS] HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
Client $client,
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
$state = new PaginationState(offset: $offset);
$endpoint = Client::BASE_URL . "/crm/v3/objects/{$type}/search";
$defaultFilter = $payload['filters'] ?? [];
$resultsPerPage = PayloadBuilder::MAX_SEARCH_REQUEST_LIMIT;
$teamId = $client->getConfig()->getTeam()->getId();
$delay = $this->calculateDelayInMicroseconds();
do {
// if ($this->shouldStopPagination($state, $teamId)) {
// break;
// }
$payload = $this->handlePaginationStrategy($payload, $defaultFilter, $state, $resultsPerPage, $teamId);
// $this->validateTokenIfNeeded($client, $state);
// usleep($delay);
$page = $this->executeSearchRequest($client, $endpoint, $payload, $state);
// $state->setTotal($page['total'] ?? 0);
// $this->updateLastRecordId($page, $state);
//
// // Safely iterate over results with null check
// $results = $page['results'] ?? [];
// foreach ($results as $row) {
// $state->incrementTotalRecords();
// yield $row;
// }
//
// $state->setOffset($this->getNextOffset($page));
// $state->incrementRequestCount();
//
// $this->logPaginationProgress($state, $teamId, $endpoint);
} while ($state->offset && ! empty($page['results']));
// Log final pagination completion stats
$this->logger->info('[Hubspot] Pagination completed', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'total_requests' => $state->requestCount,
'total_records_fetched' => $state->totalRecords,
'total_elapsed_seconds' => round($state->getElapsedSeconds(), 2),
'average_seconds_per_request' => $state->requestCount > 0 ? round($state->getElapsedSeconds() / $state->requestCount, 2) : 0,
]);
// Update reference parameters
$total = $state->total;
$lastRecordId = $state->lastRecordId;
}
private function shouldStopPagination(PaginationState $state, int $teamId): bool
{
if ($state->hasReachedSafetyLimit()) {
$this->logger->warning('[Hubspot] Reached maximum request limit during pagination', [
'team_id' => $teamId,
'safety_limit' => PaginationConfig::LOOP_SAFETY_LIMIT,
'total_fetched' => $state->totalRecords,
]);
return true;
}
return false;
}
private function handlePaginationStrategy(
array $payload,
array $defaultFilter,
PaginationState $state,
int $resultsPerPage,
int $teamId
): array {
if ($this->shouldSwitchToKeysetPagination($state, $resultsPerPage)) {
$payload['filters'] = $defaultFilter;
$payload['filters'][] = [
'propertyName' => 'hs_object_id',
'operator' => 'LT',
'value' => $state->lastRecordId,
];
$this->logger->info('[Hubspot] Search keyset pagination request', [
'team_id' => $teamId,
'sequence' => $state->requestCount,
'itemsPerPage' => $resultsPerPage,
'payload' => $payload,
'total' => $state->total,
]);
unset($payload['after']);
$state->setOffset(0);
}
if ($state->offset) {
$payload['after'] = $state->offset;
}
return $payload;
}
private function shouldSwitchToKeysetPagination(PaginationState $state, int $resultsPerPage): bool
{
// Check if we've hit the offset limit
$shouldSwitch = $state->requestCount > 0 && ($state->offset + $resultsPerPage) > PaginationConfig::TOTAL_QUERY_LIMIT;
if ($shouldSwitch && $state->lastRecordId === null) {
$this->logger->warning('[Hubspot] Cannot switch to keyset pagination: lastRecordId is null', [
'request_count' => $state->requestCount,
'current_offset' => $state->offset,
'results_per_page' => $resultsPerPage,
'total_query_limit' => PaginationConfig::TOTAL_QUERY_LIMIT,
]);
return false; // Continue with offset pagination
}
return $shouldSwitch;
}
private function validateTokenIfNeeded(Client $client, PaginationState $state): void
{
if ($state->shouldValidateToken()) {
$client->ensureValidToken();
$state->updateLastTokenCheck();
}
}
private function executeSearchRequest(Client $client, string $endpoint, array $payload, PaginationState $state): array
{
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
return $response->toArray();
} catch (\Exception $e) {
if ($client->isUnauthorizedException($e)) {
$this->logger->warning('[Hubspot] Got 401 during pagination, attempting token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'error' => $e->getMessage(),
]);
$client->ensureValidToken();
$state->updateLastTokenCheck();
try {
$response = $client->getInstance()->getClient()->request('POST', $endpoint, ['json' => $payload]);
$this->logger->info('[Hubspot] Token refresh and retry successful', [
'team_id' => $client->getConfig()->getTeam()->getId(),
]);
return $response->toArray();
} catch (\Exception $retryException) {
$this->logger->error('[Hubspot] Retry request failed after token refresh', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'original_error' => $e->getMessage(),
'retry_error' => $retryException->getMessage(),
]);
throw $retryException;
}
} else if ($client->isHubspotRateLimit($e)) {
$retryAfter = $client->parseRetryAfter($e);
$this->logger->info('[Hubspot] Received 429 from API', [
'team_id' => $client->getConfig()->getTeam()->getId(),
'config_id' => $client->getConfig()->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
} else {
throw $e;
}
}
}
private function updateLastRecordId(array $page, PaginationState $state): void
{
$lastRecord = ! empty($page['results']) ? end($page['results']) : null;
$lastRecordId = $lastRecord['id'] ?? null;
$state->updateLastRecordId($lastRecordId);
}
private function getNextOffset(array $page): int
{
return isset($page['paging']['next']['after']) ? (int) $page['paging']['next']['after'] : 0;
}
private function logPaginationProgress(PaginationState $state, int $teamId, string $endpoint): void
{
if ($state->shouldLogProgress()) {
$this->logger->info('[Hubspot] Pagination progress log', [
'team_id' => $teamId,
'endpoint' => $endpoint,
'requests_made' => $state->requestCount,
'records_fetched' => $state->totalRecords,
'elapsed_seconds' => $state->getElapsedSeconds(),
]);
}
}
private function calculateDelayInMicroseconds(): int
{
return (int) (1 / PaginationConfig::SEARCH_RPS_LIMIT * 1000000);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4247
|
NULL
|
NULL
|
NULL
|
|
4248
|
152
|
20
|
2026-05-07T13:20:48.392066+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160048392_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":0,"total_records_fetched":0,"total_elapsed_seconds":0.52,"average_seconds_per_request":0} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.ERROR: Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {"exception":"[object] (TypeError(code: 0): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","depth":4,"bounds":{"left":0.41422874,"top":0.09736632,"width":0.58577126,"height":0.8818835},"on_screen":true,"value":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6921962725416879589
|
-8161648376329334909
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":0,"total_records_fetched":0,"total_elapsed_seconds":0.52,"average_seconds_per_request":0} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.ERROR: Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {"exception":"[object] (TypeError(code: 0): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4247
|
151
|
21
|
2026-05-07T13:20:48.281567+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160048281_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":0,"total_records_fetched":0,"total_elapsed_seconds":0.52,"average_seconds_per_request":0} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.ERROR: Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {"exception":"[object] (TypeError(code: 0): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","depth":4,"on_screen":true,"value":"[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.52,\"average_seconds_per_request\":0} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}\n[2026-05-07 13:20:37] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#19 {main}\n\"} {\"correlation_id\":\"d957f311-f3c3-4899-b7a0-393eb5418938\",\"trace_id\":\"4cee629b-1a78-4aa0-a34a-3bf75220e314\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6921962725416879589
|
-8161648376329334909
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":0,"total_records_fetched":0,"total_elapsed_seconds":0.52,"average_seconds_per_request":0} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}
[2026-05-07 13:20:37] local.ERROR: Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {"exception":"[object] (TypeError(code: 0): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:83)
[stacktrace]
#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(195): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\Services\\Crm\\Hubspot\\Client), Array, 'contact', 0, 0, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(176): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)
#2 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\Services\\Crm\\Hubspot\\Client->getPaginatedData(Array, 'contact')
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\Services\\Crm\\Hubspot\\Service->matchByName('Robot')
#4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\Console\\Commands\\JiminnyDebugCommand->rateLimit()
#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\Console\\Commands\\JiminnyDebugCommand->handle(Object(Jiminny\\Jobs\\JobDispatcher), Object(Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService), Object(Jiminny\\Repositories\\AutomatedReportsRepository), Object(Jiminny\\Services\\UserPilot\\UserPilotClient))
#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container->call(Array)
#11 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#13 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#15 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /home/jiminny/artisan(13): Illuminate\\Foundation\\Application->handleCommand(Object(Symfony\\Component\\Console\\Input\\ArgvInput))
#19 {main}
"} {"correlation_id":"d957f311-f3c3-4899-b7a0-393eb5418938","trace_id":"4cee629b-1a78-4aa0-a34a-3bf75220e314"}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4242
|
152
|
17
|
2026-05-07T13:20:17.632310+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160017632_m2.jpg...
|
PhpStorm
|
faVsco.js – custom.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormVIewINavigarecodeFV faVsco.js?9 master kPr PhostormVIewINavigarecodeFV faVsco.js?9 master kProledey© Client.php X(C) TranscodeParameterRescl© HubspotPagi© UserService.php© Uuid.php> D TraitsD UseCases> D User> D Utils› D Validation> OvOphp nelpers.ong© InitialFrontendState.php© Jiminny.phpc) Plan.oho© Serializer.phpC) TeamScimDetails.ohpbootstrap>© build.> contia>D contrib→ database>O docsM front-end>D lang> node_modules library rootM ohostan>D public>O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.onopnp customer_api.onppnp embedded.ongpnp nealtn.onppnp scim.onophp uprotectedweb.phpphp web.phpphp webhook.php>O scriptsv O storage•aoo>M debugbarM frameworkv Mloas.aitianoreê audio. wav= custom.loalJiminnyDeougcommano.phpT OpportunitySyncTrait.phpC) Hubspotsinglesyncstrategy.php© WebhookSyncBatchProcessor.phcImportbatchJoblrait.ono(C) Hubspot/Service.pho© Companies.phc(C) MatchActivityermData.pho(C) CrmActivityService.phpC) CachedCrmServiceDecorator.php* Hubspot/.../SyncCrmEntitiesTrait.php©) Pipedrive/Service.php0 Servicelntertace.php@ OpportunitvSvncTest.oho(C) RateLimit.ohocllass Uuient extends Basedlient imoilements Huhsnotu ientinterfaceM A2 469 X2^ Y114115117136139142 @t ›147 Gt›156 Gt ›= hubspot-journal-poll.log= laravel log< nhnunit ymus tht isnrivate function executeRequesticallable Sanicallalihrow serZ usagespublic function isHubspotRateLimit(Throwable Se): boolmethod: 'qetCode') && (int) Se->qetCode@ === 429:public function parseRetrvAfter(Throwable Se): intif (method exists(Se.'aetResnonseHeaders'))&Sheaders = $e->getResponseHeaders ?: LJ:Svalue = Sheadensf'Retry-Aften'] 22 Sheaders("retrv-aften' 22 null.if (is arnav(Svalue)) {nel: 'custom channel")-sinfo(+Sheadens , pup=PHP_ElII1Svalue = Svaluel0l 22 null.1f&ie numenic(cvaltie))dreturn (int) $value;recurn 10"public function getMinimumApiVersion: string{...}public function getInstance@: Factoryf...,public function getNewInstance@: Discovery{...}l* Secondlu and dailu limits for Hubspot APTarQube for IDE suggestions: Detect more security issues in your PHP files // Try SonarQube Cloud for free // Download SonarQube Server // Learn more // Don't ask again (today 10:25)= custom.log X= laravel.log SF [jiminny@localhost]A console (PROD]A console (EU]A console [STAGING]4 HS_local jiminny@localhost]iti accounts (jiminny@localhost]Lukas/Stefka 121 - in 1h 10 m100% 12Thu 7 May 16:20:17U AskJiminnyReportActivityServiceTest vCascadeHubspot Rate LimitingHubSpot Rate Limit H+0 ..How to Access the Header in Your codeIf you need to check the header manually for debugging:• php// For new SDK (ApiException)trySresponse = Sclient->request...:} catch (\HubSpot\Client\Crm\Objects\ApiException $e) {SretryAfter = $headers ('Retry-After'][0] ?? $headers['retry-after'] [0] ?? null;f(SretrvAfter)// HubSpot sent retry guidance} else{/ No header - use detault based on error messageShody = ison decode(Se-saetResponseBodvo). true):SretryAfter = match($body['policyName'] ?? null) {detault = 10,RecommendationThe current imolementation at Service.oho: 1721-1727 already handles this correctly by checking policyName:•phpsresponse =son decodelse->geckesponsebody, truen&& Sresponsel'policyName'] == self::TEN SECONDLY ROLLING POLICY: 1; // Default 1 second for other limitsTo see if headers are actually present, add temporary logging:phoSheaders = se->oetResponseHeaderso?::Log: : debug(' [HubS:ot] Rate limit response headers', [headers = Sheaders,'retry_after' => $headers ['Retry-After'] ?? $headers['retry-after'] ?? 'NOT_PRESENT',1):.nl .Ask anvthina (*4L)C° AdantiveW Windsurf Teame1-1UTE.8io 4 spaces...
|
NULL
|
6358306397148738675
|
NULL
|
click
|
ocr
|
NULL
|
PhostormVIewINavigarecodeFV faVsco.js?9 master kPr PhostormVIewINavigarecodeFV faVsco.js?9 master kProledey© Client.php X(C) TranscodeParameterRescl© HubspotPagi© UserService.php© Uuid.php> D TraitsD UseCases> D User> D Utils› D Validation> OvOphp nelpers.ong© InitialFrontendState.php© Jiminny.phpc) Plan.oho© Serializer.phpC) TeamScimDetails.ohpbootstrap>© build.> contia>D contrib→ database>O docsM front-end>D lang> node_modules library rootM ohostan>D public>O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.onopnp customer_api.onppnp embedded.ongpnp nealtn.onppnp scim.onophp uprotectedweb.phpphp web.phpphp webhook.php>O scriptsv O storage•aoo>M debugbarM frameworkv Mloas.aitianoreê audio. wav= custom.loalJiminnyDeougcommano.phpT OpportunitySyncTrait.phpC) Hubspotsinglesyncstrategy.php© WebhookSyncBatchProcessor.phcImportbatchJoblrait.ono(C) Hubspot/Service.pho© Companies.phc(C) MatchActivityermData.pho(C) CrmActivityService.phpC) CachedCrmServiceDecorator.php* Hubspot/.../SyncCrmEntitiesTrait.php©) Pipedrive/Service.php0 Servicelntertace.php@ OpportunitvSvncTest.oho(C) RateLimit.ohocllass Uuient extends Basedlient imoilements Huhsnotu ientinterfaceM A2 469 X2^ Y114115117136139142 @t ›147 Gt›156 Gt ›= hubspot-journal-poll.log= laravel log< nhnunit ymus tht isnrivate function executeRequesticallable Sanicallalihrow serZ usagespublic function isHubspotRateLimit(Throwable Se): boolmethod: 'qetCode') && (int) Se->qetCode@ === 429:public function parseRetrvAfter(Throwable Se): intif (method exists(Se.'aetResnonseHeaders'))&Sheaders = $e->getResponseHeaders ?: LJ:Svalue = Sheadensf'Retry-Aften'] 22 Sheaders("retrv-aften' 22 null.if (is arnav(Svalue)) {nel: 'custom channel")-sinfo(+Sheadens , pup=PHP_ElII1Svalue = Svaluel0l 22 null.1f&ie numenic(cvaltie))dreturn (int) $value;recurn 10"public function getMinimumApiVersion: string{...}public function getInstance@: Factoryf...,public function getNewInstance@: Discovery{...}l* Secondlu and dailu limits for Hubspot APTarQube for IDE suggestions: Detect more security issues in your PHP files // Try SonarQube Cloud for free // Download SonarQube Server // Learn more // Don't ask again (today 10:25)= custom.log X= laravel.log SF [jiminny@localhost]A console (PROD]A console (EU]A console [STAGING]4 HS_local jiminny@localhost]iti accounts (jiminny@localhost]Lukas/Stefka 121 - in 1h 10 m100% 12Thu 7 May 16:20:17U AskJiminnyReportActivityServiceTest vCascadeHubspot Rate LimitingHubSpot Rate Limit H+0 ..How to Access the Header in Your codeIf you need to check the header manually for debugging:• php// For new SDK (ApiException)trySresponse = Sclient->request...:} catch (\HubSpot\Client\Crm\Objects\ApiException $e) {SretryAfter = $headers ('Retry-After'][0] ?? $headers['retry-after'] [0] ?? null;f(SretrvAfter)// HubSpot sent retry guidance} else{/ No header - use detault based on error messageShody = ison decode(Se-saetResponseBodvo). true):SretryAfter = match($body['policyName'] ?? null) {detault = 10,RecommendationThe current imolementation at Service.oho: 1721-1727 already handles this correctly by checking policyName:•phpsresponse =son decodelse->geckesponsebody, truen&& Sresponsel'policyName'] == self::TEN SECONDLY ROLLING POLICY: 1; // Default 1 second for other limitsTo see if headers are actually present, add temporary logging:phoSheaders = se->oetResponseHeaderso?::Log: : debug(' [HubS:ot] Rate limit response headers', [headers = Sheaders,'retry_after' => $headers ['Retry-After'] ?? $headers['retry-after'] ?? 'NOT_PRESENT',1):.nl .Ask anvthina (*4L)C° AdantiveW Windsurf Teame1-1UTE.8io 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4239
|
152
|
15
|
2026-05-07T13:20:15.163300+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160015163_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":4,"bounds":{"left":0.41422874,"top":0.09736632,"width":0.2975399,"height":0.8818835},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8778260184964073647
|
6378757184196315236
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4238
|
151
|
17
|
2026-05-07T13:20:11.818565+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160011818_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
6041807037674716912
|
-8348188946929047100
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
iTerm2• •ShellEditViewSessionScriptsProfilesWindowHelpLukas/Stefka 121 • in 1h 10 m100% <78DEV (docker)DOCKERO 81DEV (docker)H82APP (-zsh)-zsh• 84screenpipe"configcachecompiledeventsroutesviewsworker-nudges:worker-nudges_00:stoppedjiminny-worker-processing-2: jiminny-worker-processing-2_00: stoppedjiminny-worker-processing-3:jiminny-worker-processing-3_00: stoppedjiminny-worker-processing-4:jiminny-worker-processing-4_00: stoppedjiminny-worker-processing-5:jiminny-worker-processing-5_00:stoppedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: stoppedworker-analytics:worker-analytics_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedartisan-schedule:artisan-schedule_00:stoppedworker-audio:worker-audio_00: stoppedjiminny-worker-processing-1:jiminny-worker-processing-1_00: stoppedworker:worker_00: stoppedworker-calendar:worker-calendar_00: stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedworker-emails:worker-emails_00: stoppedworker-es-update:worker-es-update_00: stoppedartisan-schedule:artisan-schedule_00: startedjiminny-worker-processing-1:jiminny-worker-processing-1_00: startedjiminny-worker-processing-2:jiminny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed:jiminny-worker-processing-delayed_00:startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00: startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00:startedroot@docker_lamp_1:/home/jiminny# l•₴555.84ms DONE108.68ms DONE22.07ms DONE25.86ms DONE19.91ms DONE52.25ms DONE-zshThu 7 May 16:20:12T₴1₴6DEV...
|
4236
|
NULL
|
NULL
|
NULL
|
|
4237
|
152
|
14
|
2026-05-07T13:20:10.941443+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160010941_m2.jpg...
|
PhpStorm
|
faVsco.js – custom.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Editor for custom.log","depth":4,"bounds":{"left":0.41422874,"top":0.09736632,"width":0.2975399,"height":0.8818835},"on_screen":true,"role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8857621970239421474
|
6378757184196315236
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4234
|
NULL
|
NULL
|
NULL
|
|
4236
|
151
|
16
|
2026-05-07T13:20:10.854084+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778160010854_m1.jpg...
|
PhpStorm
|
faVsco.js – custom.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"Editor for custom.log","depth":4,"on_screen":true,"role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.016666668,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8857621970239421474
|
6378757184196315236
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4235
|
151
|
15
|
2026-05-07T13:19:58.888875+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159998888_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1532741602741256285
|
-8240454672726253758
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(all# Lukas/Stefka 121 - in 1h 11 m100% <78Thu 7 May 16:19:59DEV (docker)DOCKERDEV (docker)H82worker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00: startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00: startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugMatching contact 0APP (-zsh)-zsh• 84screenpipe*SevenShores\Hubspot\Exceptions\BadRequestClient error: 'POST [URL_WITH_CREDENTIALS] php artisan optimize:clear && supervisorctl restart allINFOClearing cached bootstrap files.configcachecompiledeventsroutesviews55.84ms DONE108.68ms DONE22.07ms DONE25.86ms DONE19.91ms DONE52.25ms DONE...
|
4233
|
NULL
|
NULL
|
NULL
|
|
4234
|
152
|
13
|
2026-05-07T13:19:56.097043+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159996097_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.39926863,"top":0.105347164,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.4119016,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"bounds":{"left":0.42287233,"top":0.10454908,"width":0.043882977,"height":0.015961692},"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.47573137,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.48570478,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4943484,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.50299203,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"bounds":{"left":0.51662236,"top":0.103751,"width":0.025598405,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.5422208,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.55086434,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.55950797,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.5681516,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.6988032,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":4,"bounds":{"left":0.41422874,"top":0.13088587,"width":0.2975399,"height":0.84836394},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"}]...
|
-796838314372468766
|
5225835679589468260
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4233
|
151
|
14
|
2026-05-07T13:19:54.272815+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159994272_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8043719072324535154
|
-8628527368849355612
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
iTerm2ShellEditViewSessio Project: faVsco.js, menu
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ab)= Lukas/Stefka 121 - in 1h 11 mA100% <78Thu 7 May 16:19:55DEV (docker)*3T₴1DOCKERO &1DEV (docker)882APP (-zsh)jiminny-worker-processing-3:j1minny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-workonИИАРАССКА ААTAA АЛ. СLАnbААworker:worker_00: startedworker-analytics:worker-analytics_00: startecworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00:startedworker-conferences:worker-conferences_00: stcA.Clear Laravel logworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: stariworker-download:worker-download_00:startedClaude.app/Applications/Claude.appworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startecworker-nudges:worker-nudges_00: startedCleanShot X.app/Applications/CleanShot X.approot@docker_lamp_1:/home/jiminny# php artisarMatching contact 0-zsh• 84|screenpipe*•$5SevenShores\Hubspot\Exceptions\BadRequestMonitorControlLite.app/Applications/MonitorControlLite.appiCloud DriveOpen iCloud Drive in FinderClient error: 'POST [URL_WITH_CREDENTIALS] php artisan optimize:clear && supervisorctl restart all...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4232
|
152
|
12
|
2026-05-07T13:19:51.844862+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159991844_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormVIewINavigarecodeFV faVsco.js°9 master kPr PhostormVIewINavigarecodeFV faVsco.js°9 master kProiect v© Client.php X(C) TranscodeParameterRescl© HubspotPagi© UserService.php© Uuid.php> D TraitsD UseCases> D User> D Utils› D Validation> OvOphp nelpers.ong© InitialFrontendState.php© Jiminny.phpc) Plan.oho© Serializer.phpC) TeamScimDetails.ohpbootstrap>© build.> contia> O contrib.→ database>O docsM front-end>D lang> node_modules library rootM ohostan>D public>O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.onopnp customer_api.onppnp embedded.ongpnp nealtn.onppnp scim.onophp uprotectedweb.phpphp web.phpphp webhook.php>O scriptsv O storage>M debugbarM frameworkv Mloas.aitianoreê audio. wav= custom.loalJiminnyDeougcommano.phpT OpportunitySyncTrait.phpC) Hubspotsinglesyncstrategy.php© WebhookSyncBatchProcessor.phcImportbatchJoblrait.ono(C) Hubspot/Service.pho© Companies.phc(C) MatchActivityermData.pho(C) CrmActivityService.phpC) CachedCrmServiceDecorator.php* Hubspot/.../SyncCrmEntitiesTrait.php©) Pipedrive/Service.php0 Servicelntertace.php@' OpportunitvSvncTest.ohp(C) RateLimit.ohocllass Uuient extends Basedlient imoilements Huhsnotu ientinterfaceA2 A69V2 ^ V114115117136139142 @t ›147 Gt›156 Gt ›= hubspot-journal-poll.log= laravel log161< nhnunit ymus tht isnrivate function executeRequesticallable Sanicallalihrow serZ usagespublic function isHubspotRateLimit(Throwable Se): boolmethod: 'qetCode') && (int) Se->qetCode@ === 429:public function parseRetrvAfter(Throwable Se): intif (method exists(Se.'aetResnonseHeaders'))&Sheaders = $e->getResponseHeaders ?: LJ:Svalue = Sheadensi'Retry-Aften'] 22 Sheadens('retrv-aften! 22 null.if (is arnav(Svalue)) {net rcueton ahennellg-sinfolishendene 1 pHe-• ГПr-cTIISvalue = Svaluel0l 22 null.1f oie numenic(svalte))dreturn (int) $value;recurn 10"public function getMinimumApiVersion: string{...}public function getInstance@: Factoryf...,public function getNewInstance@: Discovery{...}l* Secondlu and dailu limits for Hubspot APTDDTLД TI 1 MMНarQube for IDE suggestions: Detect more security issues in your PHP files // Try SonarQube Cloud for free // Download SonarQube Server // Learn more // Don't ask again (today 10:25)=custom.log=laravel.log X 4 SF jiminny@localhost]4 HS_local [iminny@localhost]iti accounts (jiminny@localhost]A console (PROD]A console (EU]A console [STAGING]x 5 CcW .*TLY:"Lukas sterka 121. In ih 11mU AskJiminnyReportActivityServiceTest vCascadeHubspot Rate LimitingHubspot Rate Limit HHow to Access the Header in Your CodeIt you need to check the header manually for debugging:"phpFor new SDK (Ap1Except1on)try{Cresnonse = Sclient->request(...;} catch (\HubSpot\Client\Crm\Objects\ApiException Se) ‹Sheaders = $e->getResponseHeaders() ?: []:SretryAfter = Sheaders 'Retry-Atter'10 ?? Sheaders "retry-atter 0 7? nuul:if (SretryAfter) {sent retry guidancesteepttanosrethyatcer),•else «I No headerSbody = ison decode(Se->getResponseBody(), true):SretryAftercvName'] 22 null) {TEN-SELUNDLT_KULLING→ 10,"SECONDLY=>1.default = 10.RecommendationThe current imolementation at Service.pho: 1721-1727 already handles this correctly by checkina policvName :^ ohoSresponse = json_decode($e->getResponseBody(), true);sretryAtter =isset (Sresponse['policvName'] )Sc Sresnonsef'nolicvame'1 ==self.-TEN SECONDLY ROLLING POLTC# 10 coconde•1: // Default 1 second for other limitsTo see if headers are actually present, add temporary logging:• php$headers = $e->getResponseHeaders() ?: []:Loa::debua" HubSpot) Rate Limitnse headers'. ['headersi = Cheaderç.'retry after' = Sheaders ('Retry-After'] ?? Sheaders('retry-after'] ?? 'NOT_PRESENT'.100% 12Thu 7 May 16:19:52+0 ..Ask anvthina (*4L)C° AdantiveGal .WN Windsurf Teamc2-1UTE.8Iio 4 spaces...
|
NULL
|
5791500814224417052
|
NULL
|
click
|
ocr
|
NULL
|
PhostormVIewINavigarecodeFV faVsco.js°9 master kPr PhostormVIewINavigarecodeFV faVsco.js°9 master kProiect v© Client.php X(C) TranscodeParameterRescl© HubspotPagi© UserService.php© Uuid.php> D TraitsD UseCases> D User> D Utils› D Validation> OvOphp nelpers.ong© InitialFrontendState.php© Jiminny.phpc) Plan.oho© Serializer.phpC) TeamScimDetails.ohpbootstrap>© build.> contia> O contrib.→ database>O docsM front-end>D lang> node_modules library rootM ohostan>D public>O resourcesv Mroutesphp api.phpphp api_v2.phppnp console.onopnp customer_api.onppnp embedded.ongpnp nealtn.onppnp scim.onophp uprotectedweb.phpphp web.phpphp webhook.php>O scriptsv O storage>M debugbarM frameworkv Mloas.aitianoreê audio. wav= custom.loalJiminnyDeougcommano.phpT OpportunitySyncTrait.phpC) Hubspotsinglesyncstrategy.php© WebhookSyncBatchProcessor.phcImportbatchJoblrait.ono(C) Hubspot/Service.pho© Companies.phc(C) MatchActivityermData.pho(C) CrmActivityService.phpC) CachedCrmServiceDecorator.php* Hubspot/.../SyncCrmEntitiesTrait.php©) Pipedrive/Service.php0 Servicelntertace.php@' OpportunitvSvncTest.ohp(C) RateLimit.ohocllass Uuient extends Basedlient imoilements Huhsnotu ientinterfaceA2 A69V2 ^ V114115117136139142 @t ›147 Gt›156 Gt ›= hubspot-journal-poll.log= laravel log161< nhnunit ymus tht isnrivate function executeRequesticallable Sanicallalihrow serZ usagespublic function isHubspotRateLimit(Throwable Se): boolmethod: 'qetCode') && (int) Se->qetCode@ === 429:public function parseRetrvAfter(Throwable Se): intif (method exists(Se.'aetResnonseHeaders'))&Sheaders = $e->getResponseHeaders ?: LJ:Svalue = Sheadensi'Retry-Aften'] 22 Sheadens('retrv-aften! 22 null.if (is arnav(Svalue)) {net rcueton ahennellg-sinfolishendene 1 pHe-• ГПr-cTIISvalue = Svaluel0l 22 null.1f oie numenic(svalte))dreturn (int) $value;recurn 10"public function getMinimumApiVersion: string{...}public function getInstance@: Factoryf...,public function getNewInstance@: Discovery{...}l* Secondlu and dailu limits for Hubspot APTDDTLД TI 1 MMНarQube for IDE suggestions: Detect more security issues in your PHP files // Try SonarQube Cloud for free // Download SonarQube Server // Learn more // Don't ask again (today 10:25)=custom.log=laravel.log X 4 SF jiminny@localhost]4 HS_local [iminny@localhost]iti accounts (jiminny@localhost]A console (PROD]A console (EU]A console [STAGING]x 5 CcW .*TLY:"Lukas sterka 121. In ih 11mU AskJiminnyReportActivityServiceTest vCascadeHubspot Rate LimitingHubspot Rate Limit HHow to Access the Header in Your CodeIt you need to check the header manually for debugging:"phpFor new SDK (Ap1Except1on)try{Cresnonse = Sclient->request(...;} catch (\HubSpot\Client\Crm\Objects\ApiException Se) ‹Sheaders = $e->getResponseHeaders() ?: []:SretryAfter = Sheaders 'Retry-Atter'10 ?? Sheaders "retry-atter 0 7? nuul:if (SretryAfter) {sent retry guidancesteepttanosrethyatcer),•else «I No headerSbody = ison decode(Se->getResponseBody(), true):SretryAftercvName'] 22 null) {TEN-SELUNDLT_KULLING→ 10,"SECONDLY=>1.default = 10.RecommendationThe current imolementation at Service.pho: 1721-1727 already handles this correctly by checkina policvName :^ ohoSresponse = json_decode($e->getResponseBody(), true);sretryAtter =isset (Sresponse['policvName'] )Sc Sresnonsef'nolicvame'1 ==self.-TEN SECONDLY ROLLING POLTC# 10 coconde•1: // Default 1 second for other limitsTo see if headers are actually present, add temporary logging:• php$headers = $e->getResponseHeaders() ?: []:Loa::debua" HubSpot) Rate Limitnse headers'. ['headersi = Cheaderç.'retry after' = Sheaders ('Retry-After'] ?? Sheaders('retry-after'] ?? 'NOT_PRESENT'.100% 12Thu 7 May 16:19:52+0 ..Ask anvthina (*4L)C° AdantiveGal .WN Windsurf Teamc2-1UTE.8Iio 4 spaces...
|
4230
|
NULL
|
NULL
|
NULL
|
|
4231
|
151
|
13
|
2026-05-07T13:19:51.982230+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159991982_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ab)# Lukas/Stefka 121 - in 1h 11 m100% <78DEV (docker)Thu 7 May 16:19:52181₴6DOCKERO &1DEV (docker)882APP (-zsh)jiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00:startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny: debugMatching contact 0-zsh• 84screenpipe*•$5-zshDEVSevenShores\Hubspot\Exceptions\BadRequestClient error: 'POST [URL_WITH_CREDENTIALS] php artisan optimize:clear && supervisorctl restart all...
|
NULL
|
3314593340847594508
|
NULL
|
click
|
ocr
|
NULL
|
iTerm2ShellEditViewSessionScriptsProfilesWindowHel iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(ab)# Lukas/Stefka 121 - in 1h 11 m100% <78DEV (docker)Thu 7 May 16:19:52181₴6DOCKERO &1DEV (docker)882APP (-zsh)jiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00:startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny: debugMatching contact 0-zsh• 84screenpipe*•$5-zshDEVSevenShores\Hubspot\Exceptions\BadRequestClient error: 'POST [URL_WITH_CREDENTIALS] php artisan optimize:clear && supervisorctl restart all...
|
4229
|
NULL
|
NULL
|
NULL
|
|
4226
|
152
|
9
|
2026-05-07T13:19:25.194496+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159965194_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.39926863,"top":0.105347164,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.4119016,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"bounds":{"left":0.42287233,"top":0.10454908,"width":0.043882977,"height":0.015961692},"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.47573137,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.48570478,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4943484,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.50299203,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"bounds":{"left":0.51662236,"top":0.103751,"width":0.025598405,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.5422208,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.55086434,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.55950797,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.5681516,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.6988032,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":4,"bounds":{"left":0.41422874,"top":0.13088587,"width":0.2975399,"height":0.84836394},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
9093516044268772725
|
5225835679589468260
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4224
|
NULL
|
NULL
|
NULL
|
|
4225
|
151
|
10
|
2026-05-07T13:19:24.195957+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159964195_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":4,"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
9093516044268772725
|
5225835679589468260
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4224
|
152
|
8
|
2026-05-07T13:18:54.675118+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159934675_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.39926863,"top":0.105347164,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.4119016,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"bounds":{"left":0.42287233,"top":0.10454908,"width":0.043882977,"height":0.015961692},"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.47573137,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.48570478,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4943484,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.50299203,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"bounds":{"left":0.51662236,"top":0.103751,"width":0.025598405,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.5422208,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.55086434,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.55950797,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.5681516,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.6988032,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":4,"bounds":{"left":0.41422874,"top":0.13088587,"width":0.2975399,"height":0.84836394},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
9093516044268772725
|
5225835679589468260
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4223
|
151
|
9
|
2026-05-07T13:18:53.706884+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159933706_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":4,"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
9093516044268772725
|
5225835679589468260
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4221
|
NULL
|
NULL
|
NULL
|
|
4222
|
152
|
7
|
2026-05-07T13:18:23.667430+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159903667_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.39926863,"top":0.105347164,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.4119016,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"bounds":{"left":0.42287233,"top":0.10454908,"width":0.043882977,"height":0.015961692},"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.47573137,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.48570478,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4943484,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.50299203,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"bounds":{"left":0.51662236,"top":0.103751,"width":0.025598405,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.5422208,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.55086434,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.55950797,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.5681516,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.6988032,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"","depth":4,"bounds":{"left":0.41422874,"top":0.13088587,"width":0.2975399,"height":0.84836394},"on_screen":true,"value":"","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"69","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
9093516044268772725
|
5225835679589468260
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
Sync Changes
Hide This Notification
Code changed:
Hide
2
69
2
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Hubspot;
use HubSpot\Client\Crm\Deals\ApiException as DealApiException;
use HubSpot\Client\Crm\Contacts\ApiException as ContactApiException;
use HubSpot\Client\Crm\Companies\ApiException as CompanyApiException;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectWithAssociations as ContactsWithAssociations;
use HubSpot\Client\Crm\Companies\Model\SimplePublicObjectWithAssociations as CompaniesWithAssociations;
use HubSpot\Client\Crm\Deals\Model\SimplePublicObjectWithAssociations as DealWithAssociations;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Objects\Model\SimplePublicObjectWithAssociations as ObjectWithAssociations;
use HubSpot\Client\Crm\Pipelines\Model\Error;
use HubSpot\Client\Crm\Pipelines\Model\PipelineStage;
use HubSpot\Client\Crm\Properties\Model\Property;
use HubSpot\Discovery\Discovery;
use Jiminny\Component\Utility\Service\ProviderRateLimiter;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\RateLimitException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Crm\Field;
use Jiminny\Services\Crm\BaseClient;
use Jiminny\Services\Crm\Hubspot\DTO\Response\Owner;
use Jiminny\Services\SocialAccountService;
use SevenShores\Hubspot\Exceptions\BadRequest;
use SevenShores\Hubspot\Exceptions\HubspotException;
use SevenShores\Hubspot\Factory;
use SevenShores\Hubspot\Http\Response;
use Jiminny\Services\Crm\Hubspot\Pagination\HubspotPaginationService;
use Throwable;
/**
* @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}
*/
class Client extends BaseClient implements HubspotClientInterface
{
public const string MIN_API_VERSION = '2';
public const string BASE_URL = '[URL_WITH_CREDENTIALS] T
* @param callable(): T $apiCall
* @return T
*
* @throws RateLimitException
*/
private function executeRequest(callable $apiCall)
{
if (! $this->rateLimiter->canMakeRequest($this->config)) {
$retryAfter = $this->rateLimiter->requestAvailableIn($this->config);
$this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
]);
throw new RateLimitException(
'Hubspot rate limit reached for configuration ' . $this->config->getId(),
$retryAfter,
);
}
$this->rateLimiter->incrementRequestCount($this->config);
try {
return $apiCall();
} catch (Throwable $e) {
if ($this->isHubspotRateLimit($e)) {
$retryAfter = $this->parseRetryAfter($e);
$this->log->warning('[Hubspot] Received 429 from API', [
'team_id' => $this->config->team_id,
'config_id' => $this->config->getId(),
'retry_after' => $retryAfter,
'reason' => $e->getMessage(),
]);
throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);
}
throw $e;
}
}
public function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
public function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$headers ' . PHP_EOL . print_r($headers, true));
$value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;
if (is_array($value)) {
$value = $value[0] ?? null;
}
if (is_numeric($value)) {
return (int) $value;
}
}
return 10;
}
public function getMinimumApiVersion(): string
{
return self::MIN_API_VERSION;
}
public function getInstance(): Factory
{
return new Factory([
'key' => $this->accessToken,
'oauth2' => true,
'base_url' => $this->baseUrl,
]);
}
public function getNewInstance(): Discovery
{
return \HubSpot\Factory::createWithAccessToken($this->accessToken);
}
/**
* Secondly and daily limits for Hubspot API
*
* Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)
* Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds
* Daily: 250,000 | 500,000 | 1,000,000
*
* Official documentation states: The search endpoints are rate limited to five requests per second.
* Since with 5 RPS were still hitting secondly rate limits we lowered it to 4
*/
public function getPaginatedData(array $payload, string $type, int $offset = 0): array
{
$total = 0;
$lastId = null;
$rows = [];
foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {
$rows[] = $row;
}
return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];
}
/**
* @throws HubspotException
* @throws SocialAccountTokenInvalidException
* @throws BadRequest
*/
public function getPaginatedDataGenerator(
array $payload,
string $type,
int $offset = 0,
int &$total = 0,
?string &$lastRecordId = null
): \Generator {
return $this->paginationService->getPaginatedDataGenerator(
$this,
$payload,
$type,
$offset,
$total,
$lastRecordId
);
}
/**
* @throws DealApiException
* @throws CrmException
*/
public function getOpportunityById(string $crmId, array $fields): array
{
try {
// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(
$crmId,
implode(',', $fields),
'companies,contacts'
);
} catch (DealApiException $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $deal instanceof DealWithAssociations) {
throw new CrmException('Deal not found');
}
return [
'id' => $deal->getId(),
'properties' => $deal->getProperties(),
'associations' => $deal->getAssociations(),
];
}
/**
* Generic batch read method for HubSpot objects
*
* @param string $objectType The object type ('deals', 'companies', 'contacts')
* @param array<string> $crmIds Array of HubSpot object IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with object data
*/
private function batchReadObjects(string $objectType, array $crmIds, array $fields): array
{
if (empty($crmIds)) {
return [];
}
$this->validateBatchSize($objectType, $crmIds);
$this->ensureValidToken();
try {
$batchConfig = $this->createBatchConfiguration($objectType);
$batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);
$response = $batchConfig['api']->read($batchReadRequest);
$this->validateApiResponse($response, $objectType);
$results = $this->processApiResults($response);
$this->logBatchResults($objectType, $crmIds, $results);
return $results;
} catch (\Throwable $e) {
$this->handleBatchError($e, $objectType, $crmIds);
}
}
private function validateBatchSize(string $objectType, array $crmIds): void
{
if (count($crmIds) > 100) {
throw new \InvalidArgumentException("Batch size cannot exceed 100 {$objectType}");
}
}
private function createBatchConfiguration(string $objectType): array
{
$configurations = [
'deals' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Deals\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Deals\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->deals()->batchApi(),
],
'companies' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Companies\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Companies\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->companies()->batchApi(),
],
'contacts' => [
'batchReadRequest' => new \HubSpot\Client\Crm\Contacts\Model\BatchReadInputSimplePublicObjectId(),
'inputClass' => \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectId::class,
'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),
],
];
if (! isset($configurations[$objectType])) {
throw new \InvalidArgumentException("Unsupported object type: {$objectType}");
}
return $configurations[$objectType];
}
private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object
{
$batchReadRequest = $batchConfig['batchReadRequest'];
$inputClass = $batchConfig['inputClass'];
$inputs = array_map(function ($crmId) use ($inputClass) {
$input = new $inputClass();
$input->setId($crmId);
return $input;
}, $crmIds);
$batchReadRequest->setInputs($inputs);
$batchReadRequest->setProperties($fields);
return $batchReadRequest;
}
private function validateApiResponse($response, string $objectType): void
{
if (! $response) {
throw new CrmException("HubSpot API returned null response for {$objectType} batch read");
}
}
private function processApiResults($response): array
{
$results = [];
$responseResults = $response->getResults();
if ($responseResults) {
foreach ($responseResults as $object) {
if ($object && $object->getId()) {
$results[$object->getId()] = [
'id' => $object->getId(),
'properties' => $object->getProperties() ?: [],
];
}
}
}
return $results;
}
private function logBatchResults(string $objectType, array $crmIds, array $results): void
{
$this->log->info("[HubSpot] Batch fetched {$objectType}", [
'requested_count' => count($crmIds),
'returned_count' => count($results),
'crm_ids' => $crmIds,
]);
}
private function handleBatchError(\Throwable $e, string $objectType, array $crmIds): void
{
$errorMessage = $e->getMessage() ?: 'Unknown error';
$errorTrace = $e->getTraceAsString() ?: 'No trace available';
$this->log->error("[HubSpot] Failed to batch fetch {$objectType}", [
'crm_ids' => $crmIds,
'error' => $errorMessage,
'trace' => $errorTrace,
]);
throw new CrmException("Failed to batch fetch {$objectType}: " . $errorMessage);
}
/**
* Batch read multiple opportunities by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot deal IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with opportunity data
*/
public function getOpportunitiesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('deals', $crmIds, $fields);
}
/**
* Batch read multiple companies by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot company IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with company data
*/
public function getCompaniesByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('companies', $crmIds, $fields);
}
/**
* Batch read multiple contacts by their CRM IDs
*
* @param array<string> $crmIds Array of HubSpot contact IDs (max 100)
* @param array<string> $fields Array of property names to fetch
*
* @return array<string, array> Array keyed by CRM ID with contact data
*/
public function getContactsByIds(array $crmIds, array $fields): array
{
return $this->batchReadObjects('contacts', $crmIds, $fields);
}
/**
* @throws CompanyApiException
* @throws CrmException
*/
public function getAccountById(string $crmId, array $fields): array
{
try {
$company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(
$crmId,
implode(',', $fields),
);
} catch (CompanyApiException $e) {
$this->log->info('[Hubspot] Failed to fetch account', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $company instanceof CompaniesWithAssociations) {
throw new CrmException('Account not found');
}
return [
'id' => $company->getId(),
'properties' => $company->getProperties(),
];
}
/**
* @throws ContactApiException
* @throws CrmException
*/
public function getContactById(string $crmId, array $fields): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$crmId,
implode(',', $fields)
);
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'crm_id' => $crmId,
'reason' => $e->getMessage(),
]);
throw $e;
}
if (! $contact instanceof ContactsWithAssociations) {
throw new CrmException('Contact not found');
}
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
}
/**
* This is email search request that Hubspot offers as GET (more generous quota)
*/
public function getContactByEmail(string $email, array $fields = []): array
{
try {
$contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(
$email,
implode(',', $fields),
null,
false,
'email'
);
return [
'id' => $contact->getId(),
'properties' => $contact->getProperties(),
];
} catch (ContactApiException $e) {
$this->log->info('[Hubspot] Failed to fetch contact', [
'email' => $email,
'reason' => $e->getMessage(),
]);
return [];
}
}
/**
* @throws CrmException
*/
public function fetchProperty(string $objectType, string $propertyId): Property
{
$result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);
if (! $result instanceof Property) {
$this->log->error('[Hubspot] Failed to fetch property', [
'object_type' => $objectType,
'property_id' => $propertyId,
'reason' => $result->getMessage(),
]);
throw new CrmException('Failed to fetch property');
}
return $result;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchPropertyOptions(string $objectType, string $propertyId): array
{
/** @var array<CrmFieldOption> */
return $this->fetchProperty($objectType, $propertyId)->getOptions();
}
/**
* @return array<array{id:string, label:string, deleted:bool}>
*/
public function fetchCallDispositions(): array
{
/** @var Response $response */
$response = $this->getInstance()->engagements()->getCallDispositions();
/**
* @var array<array{
* id:string,
* label:string,
* deleted: bool
* }>
*/
return $response->toArray();
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityPipelineStages(): array
{
$stages = [];
$apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');
if ($apiResponse instanceof Error) {
$this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $apiResponse->getMessage(),
]);
return [];
}
foreach ($apiResponse->getResults() as $pipeline) {
$pipelineStages = array_map(
static function (PipelineStage $stage) {
return [
'id' => $stage->getId(),
'label' => $stage->getLabel(),
];
},
$pipeline->getStages()
);
$stages = array_merge($stages, $pipelineStages);
}
return $stages;
}
public function fetchOpportunityPipelines(): array
{
$pipelines = [];
try {
$apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');
} catch (\Exception $e) {
$this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [
'reason' => $e->getMessage(),
]);
return [];
}
$response = $apiResponse->toArray();
foreach ($response['results'] as $pipeline) {
$pipelines[] = [
'id' => $pipeline['id'],
'label' => $pipeline['label'],
];
}
return $pipelines;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchMeetingOutcomeFieldOptions(Field $field): array
{
return $field->getCrmProviderId() === 'meetingOutcome'
? $this->fetchMeetingOutcomeTypes()
: $this->fetchCallActivityTypes();
}
public function fetchMeetingOutcomeTypes(): array
{
return $this->extractMeetingTypeOptions(
'[URL_WITH_CREDENTIALS] Response $response */
$response = $this->getInstance()
->getClient()
->request('GET', $endpoint);
/**
* @var array<array{
* value: string,
* label: string,
* displayOrder: int
* }> $optionData
*/
$optionData = $response->toArray()['options'] ?? [];
$options = [];
foreach ($optionData as $item) {
$options[] = [
'id' => $item['value'],
'value' => $item['value'],
'label' => $item['label'],
'display_order' => $item['displayOrder'],
];
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchDispositionFieldOptions(): array
{
$options = [];
$dispositions = $this->fetchCallDispositions();
foreach ($dispositions as $disposition) {
if ($disposition['deleted'] !== false) {
continue;
}
$option['value'] = $disposition['id'];
$option['id'] = $disposition['id'];
$option['label'] = $disposition['label'];
$options[] = $option;
}
return $options;
}
/**
* @return array<CrmFieldOption>
*/
public function fetchOpportunityFieldOptions(Field $field): array
{
if ($field->isStageField()) {
return $this->fetchOpportunityPipelineStages();
}
if ($field->isPipelineField()) {
return $this->fetchOpportunityPipelines();
}
return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)
{
$endpoint = self::BASE_URL . $endpoint;
if ($method === 'GET') {
$response = $this->getInstance()->getClient()?->request(
method: $method,
endpoint: $endpoint,
query_string: $queryString
);
} else {
$response = $this->getInstance()->getClient()->request($method, $endpoint, [
'json' => ($payload),
]);
}
$max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // "110"
$remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // "109"
$interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // "10000"
$body = json_decode((string) $response->getBody(), true);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));
return $response;
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function createMeeting(array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings';
return $this->makeRequest($endpoint, 'POST', $payload);
}
/**
* @throws BadRequest
* @throws HubspotException
*/
public function updateMeeting(string $meetingId, array $payload): Response
{
$endpoint = '/crm/v3/objects/meetings/' . $meetingId;
return $this->makeRequest($endpoint, 'PATCH', $payload);
}
/**
* @throws \Exception
*/
public function createNote(
string $body,
string $ownerId,
int $timestamp,
string $objectId,
NoteObject $noteObject
): ?string {
try {
$noteInput = new SimplePublicObjectInput([
'properties' => [
'hs_note_body' => $body,
'hubspot_owner_id' => $ownerId,
'hs_timestamp' => $timestamp,
],
]);
// Create note
$note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);
$this->getNewInstance()->crm()->objects()->associationsApi()->create(
'note',
$note->getId(),
$this->getNoteObject($noteObject),
$objectId,
$this->getNoteAssociationType($noteObject),
);
return $note->getId();
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to create note', [
'objectId' => $objectId,
'noteObject' => $noteObject->getObjectType(),
'reason' => $e->getMessage(),
]);
\Sentry::captureException($e);
}
return null;
}
public function updateEngagement(string $objectId, array $engagement, array $metadata): void
{
$this->getInstance()->engagements()->update($objectId, $engagement, $metadata);
}
public function getEngagementData(string $engagementId): array
{
$engagement = $this->getInstance()->engagements()->get($engagementId);
return $engagement->toArray();
}
public function createEngagement(array $engagement, array $associations, array $metadata): Response
{
return $this->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
}
public function isUnauthorizedException(\Exception $e): bool
{
// Check for specific HubSpot API exception types first
if ($e instanceof BadRequest) {
// BadRequest can contain 401 status codes
return $e->getCode() === 401;
}
// Check for HTTP client exceptions with status codes
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$response = $e->getResponse();
if ($response !== null) {
return $response->getStatusCode() === 401;
}
}
// Check for Guzzle HTTP exceptions
if ($e instanceof \GuzzleHttp\Exception\ClientException) {
return $e->getCode() === 401;
}
// Fallback to string matching as last resort, but be more specific
$message = strtolower($e->getMessage());
return str_contains($message, '401 unauthorized') ||
str_contains($message, 'http 401') ||
str_contains($message, 'status code 401') ||
(preg_match('/\b401\b/', $message) && str_contains($message, 'unauthorized'));
}
/**
* Validates and refreshes the access token if needed before API requests.
* This ensures long-running processes don't fail due to token expiration.
*
* @throws SocialAccountTokenInvalidException
*/
public function ensureValidToken(): void
{
if ($this->oauthAccount === null) {
return;
}
$newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);
if ($newToken !== null) {
$this->accessToken = $newToken;
}
}
public function getConfig()
{
return $this->config;
}
// returns only active (archived=false)
public function getOwners(): array
{
return $this->getNewInstance()->crm()->owners()->getAll();
}
/**
* @param bool $archived
*
* @return array<Owner>|[]
*/
public function getOwnersArchived(bool $archived = true): array
{
$endpoint = '/crm/v3/owners';
$queryParams = [
'archived' => $archived ? 'true' : 'false',
];
$queryString = http_build_query($queryParams);
$owners = [];
try {
$response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);
$responseData = $response?->toArray();
foreach ($responseData['results'] as $result) {
try {
$owners[] = Owner::create($result);
} catch (Throwable $e) {
$this->log->error('[HubSpot] Failed to process owner data', [
'result' => $result,
'error' => $e->getMessage(),
]);
continue;
}
}
} catch (Throwable $e) {
$this->log->error('HubSpot] Failed to fetch owners', [
'archived' => $archived,
'error' => $e->getMessage(),
]);
return [];
}
return $owners;
}
public function getMeeting(string $engagementId): ObjectWithAssociations
{
return $this->getNewInstance()->crm()->objects()->basicApi()
->getById('meeting', $engagementId, null, 'contact,company,deal');
}
public function deleteEngagement(string $engagementId): void
{
$this->getInstance()->engagements()->delete((int) $engagementId);
}
public function getAssociationsData(array $ids, string $fromObject, string $toObject): array
{
$associationData = [];
$idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);
foreach ($idChunks as $idChunk) {
try {
$batchInput = new \HubSpot\Client\Crm\Associations\Model\BatchInputPublicObjectId();
$batchInput->setInputs(array_map(function ($id) {
$publicObjectId = new \HubSpot\Client\Crm\Associations\Model\PublicObjectId();
$publicObjectId->setId($id);
return $publicObjectId;
}, $idChunk));
$associatedObjectsData = $this
->getNewInstance()
->crm()
->associations()
->batchApi()
->read($fromObject, $toObject, $batchInput);
if ($associatedObjectsData instanceof \HubSpot\Client\Crm\Associations\Model\BatchResponsePublicAssociationMulti) {
foreach ($associatedObjectsData->getResults() as $association) {
$from = $association->getFrom()->getId();
$toAssociations = $association->getTo();
if (! empty($toAssociations)) {
$associationData[$from] = array_map(function ($item) {
return $item->getId();
}, $toAssociations);
}
}
}
} catch (\Exception $e) {
$this->log->error('[Hubspot] Failed to fetch associations', [
'from_object' => $fromObject,
'to_object' => $toObject,
'reason' => $e->getMessage(),
]);
}
}
return $associationData;
}
/**
* @throws \Exception
*/
private function getNoteAssociationType(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'note_to_deal',
NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it
NoteObject::Account => 'note_to_company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
/**
* @throws \Exception
*/
private function getNoteObject(NoteObject $noteObject): string
{
return match($noteObject) {
NoteObject::Opportunity => 'deal',
NoteObject::Lead, NoteObject::Contact => 'contact',
NoteObject::Account => 'company',
NoteObject::Call, NoteObject::Event => throw new \Exception('Not supported'),
};
}
public function addAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/create";
return $this->makeRequest($endpoint, 'POST', $payload);
}
public function removeAssociations(string $objectType, string $associationType, array $payload): Response
{
$endpoint = "/crm/v4/associations/$objectType/$associationType/batch/archive";
return $this->makeRequest($endpoint, 'POST', $payload);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
4220
|
NULL
|
NULL
|
NULL
|
|
4221
|
151
|
8
|
2026-05-07T13:18:21.341293+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159901341_m1.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-7673782238848625796
|
-8646559087753982588
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
iTerm2ShellE Project: faVsco.js, menu
master, menu
iTerm2ShellEditViewSessionScriptsProfilesWindowHelpliholLukas/Stefka 121 - in 1h 12 m100% <78Thu 7 May 16:18:22DEV (docker)T81DOCKERO 81DEV (docker)882APP (-zsh)jiminny-worker-processing-2:j1minny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00:startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugMatchingcontact 0-zsh• x4screenpipe*•$5-zsh₴6DEVSevenShores\Hubspot\Exceptions\BadRequestClient error: *POST [URL_WITH_CREDENTIALS] ]...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4220
|
152
|
6
|
2026-05-07T13:18:17.036038+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159897036_m2.jpg...
|
PhpStorm
|
faVsco.js – laravel.log
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormINavigarecodeFV faVsco.jsProiect© TrackRec PhostormINavigarecodeFV faVsco.jsProiect© TrackRecordingFileSiz© TrackRecordingSizeEnT. ValidateSmitProspect:AjReports0 CalendarConference0 Crm> @ Bullhorn>O CloseC Copper>J Crmobiects07 DecorateActivitv• Dummy) Helpersv D HubspotAccountSyncStrate>D Actionsn ContactsuncStrateM Fields• M lournal1 Metadatalv OpportunitySyncSti>MConcerns.(c) Hubsnotl actMonC HubspotLastMor(C) Hubsnotl actMou© HubspotLastMo(C) Hubsnotl actMou© HubspotSingleS© HubspotSyncStr© HubspotWebhoo~ M Padination© HubspotPaginatil© PaginationConfi(C) PaqinationState.> D ProspectSearchStr:› D Redisv D ServiceTraits() OpportunitvSvnc() SvncCrmEntitiesT SuncFieldstirait.T. WriteCrmTrait.o• M UtilsM Webhook(C) Hubspot/Service.pho© Companies.php(C) MatchActivityermData.pho(C) CrmActivityService.php(C) CachedCrmServiceDecorator.php* Hubspot/.../SyncCrmEntitiesTrait.php©) Pipedrive/Service.php0 Servicelntertace.php@' OpportunitvSvncTest.ohp(C) RateLimit.oho© ProviderRateLimiter.phpcllass Uuient extends Basedlient imoilements Huhsnotu ientinterfaceA2 A68 V2^nrivate function executeRequest(callable Sanicallal114115IspotkateL1m1t Ihrowable se: booustsse.method: 'qetCode') && (int) Se->qetCode0 === 429:RetrvAfterThrowable Se): intAse.'aetResnonseHeadens')) $->detResnonseleadensor?:iupport \Facades\Log::channel('custom_channel')->info('$headers' . PHP_EOL • print_r(Sheaders, true));ders| 'Retry-Aften'] 22 Sheaders"'retry-aften! 22 null.$value)) {Svaluel0l 22 null.134cCvalue)))dInt) Svalne•13613714€142 Ct› .nimumApiVersion(: string{...}147 Gt › Istance@: Factoryf...}C) BatchSvncCollectot 1c/ t:wInstance@: Discovervf...}c) RatchSvncRedisSec) Client nhoC) ClocedDea|Stadecs1 Limits for Hubspot APT@ DealFieldsService r .19narAuhe for IdE suadestiions Detect more seamritvlisaues in vour D.Dfflles llia SonarAube Claud for free //lDownload SonarOnbe Server Illear more /llDonit ask adain /today 1052514 HS_local jiminny@localhostiti accounts (jiminny@localhost]# concole [STAGING1A console [PKOU.365367369371-382=385=387=389392393394397/ 399401|26-05-07 12:57:19 Local.NOTICE: Monitoring start{"correlation_id":"4c2d4775-716d-4Ca6-b94d-Cb17 m26-05-07 12:57:191 local. NOTICE: Monitoring endX971 A V26-05-07 12:57:22) Local.INF0: Jiminny Console \Commands \Command::run Memory usage before starting command ¿"comma26-05-07 12:57:22Jfor command 1"command": "mailbox(26-05-07 12:57:25) local.INF0: Jiminny Console\Commands\Command::run Memory usage before starting command 1"comma26-05-07 12:57:25Jlocal.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"s {"correlation_id":126-05-07 12:57:25 Loc0L. INF0: EmailSchedulel FINISHEd batch orocess "host"*"docker Lamo 1" "orocessed":0r *"co(26-05-07 12:57:25) local.INF0: Jiminny Console\Commands \Command::run Memory usagefor command 1"command":"mailbox126-05-07 12257-22D0cLNSO Jaiminny Consolle kommands Vommande enun Memony usade hefone stantino command "comma26-05-07 12:57:27) local.INF0: [EmailSchedule] STARTING batch create {"host":"ker_lamp_1"} {"correlation_id":"26-05-07 12:57:27] local.INF0: [EmailSchedule] FINISHED batch create {"host":"docker_lamp1"z &"cornplation id".".26-05-07 12:57:27] local.INF0: Jiminny\Console\Commands\Command::run Memory usagefor command {"command": "mailbox26-05-07 12:57:28] local.INF0: [Jiminny\Jobs \Mailbox\CreateBatches] processed 2 inboxes and created 0 batches {"us26-05-07 12:58:06] local.INF0: [SocialAccountService) Fetching token {"socialAccountId":1499,"provider":"hubspot"]26-05-07 12:58:06] local.INF0: [SocialAccountService) Token retrieved {"socialAccountId":1499,"provider":"hubspot'26-05-07 12:58:06] local.INF0: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_ic26-05-07 12:58:06] local.INF0: [Crm0wnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot26-05-07 12:58:06] local.ERROR: Client error:POST https://api.hubapi.com/crm/v3/objects/contact/search*resultectatus":"error" "message":"You have reached your secondly limit." "errorType":"RATE LIMIT" "correlationId":"019e02€exception":" obnect sevenshores Hubspot Exceptions Badkequest code:429): Client error: 'POST https://api.huhome/J1m1nny/vendor/hubspot/nubspot-php/src/exceptions/Hubspottxcept1on.pnp:24Inome/aaminny/vendor/nubspor/nubspor-oho/sccirco/ulnentonous: sevenshoresWuospor exceocions Wunsnorexceni/home/iiminny/app/Services/Crm/Hubspot/Paqination/HubspotPaqinationService.oho(163): SevenShores||Hubspot\\Httpl\(home//iiminny/aop/Services/crm/Hubsoot/Paqination/HubsootPaqinationService.ono/51: Jiminnv ServicesCrmHubso/home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPagin/home//Timinny/aop/Services/crm/Hubsoot/Client.ono/15): JiminnvServicesCrmHubspotCuient->oetPaqinatedDatahome/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny(Services\\Crm\\Hubspot|\Client->getPaginatedDaThome/aliminny/laon/console/Commands/AaminnyDebudcommand.nho./6%lliminnyServicesViom HubsnotSenvice-SmatichB/home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\Console\\Commands|JiminnyDebugCommand->home/~iminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.nhn(36):JiminnvConsoleCommands/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod:home/iiminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.ohn(96)• TlluminateContainenUtilhome /iiminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.ohn(35)• TlluminateContainenBounhome /iiminny/vendor/laravel/framework/soc/Tlluminate/Container/Containen.ohn 799)• TlluminateContainen Round/home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container/home/jiminnv/vendon/cvmfonv/concole/Command/Commandnhn(3/1)• Tlluminato|Concole||Command-seyecute(0hzect/Svmf/home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Comn/home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\Console\Command->run(Object (Symfony\Con/home/jiminny/vendor/symfony/console/Application.php(356): Symfony\Component)\Console\Application->doRunCommanc/home/jiminny/vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun(0biect/home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Cor/home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\Foundation\(/home/jiminny/artisan(13): Illuminatel(Foundation\Application->handleCommand(Obiect(Symfony)\Componentl\Console){main?evious excentionobnect(GuzzleHttp|\Exception|\ClientException(code: 429): Client error: 'POST httos://aoi.hu• Lukas sterka 121 • In ih 12mU AskJiminnyReportActivityServiceTest vCascadeHubspot Rate LimitingHubSpot Rate Limit HHow to Access the Header in Your CodeIt you need to check the header manually for debugging:"phpFor new SDK (Ap1Except1on)try{Sresponse = Sclient->request(...):} catch (\HubSpot\Client\Crm\Objects\ApiException $e) 1Sheaders = $e->getResponseHeaders() ?: []:SretryAfter = Sheaders 'Retry-Atter'10 ?? Sheaders "retry-after' 0 7? nuut:if (SretryAfter) {sent retry guidancesteepttanosrethyatcer),I No header - use default hased on error meccadeSbody = ison decode(Se->getResponseBody(), true):SretryAftercvName'] 22 null) {"TEN SELUNDLT_KULLING →> 10,"SECONDLY => 1.default = 10.RecommendationThe current imolementation at Service.pho: 1721-1727 already handles this correctly by checkina policvName :^ oho$response = json_decode($e->getResponseBody(), true);sretryAtter =isset (Sresponse['policvName'] )Sc Sresnonsef'nolicvame'1 ==self.-TEN SECONDLY ROLLING POLTC? self::TEN SECONDLY ROLLING LIMIT# 10 coconde: 1; // Default 1 second for other limitsTo see if headers are actually present, add temporary logging:• php$headers = $e->getResponseHeaders() ?: []:Loa: :debua("[HubSpot) Rate limit response headers'. ['headersi = Cheaderç.'retry after' = Sheaders ['Retry-After'] ?? Sheaders('retry-after'] ?? 'NOT_ PRESENT'.100% 12Thu 7 May 16:18:17+0 ..Gal .Ask anvthina (&4D< CodeC° AdantiveWN Windsurf Teams120-127UTC.8io 4 spaces...
|
NULL
|
-4886052850549949718
|
NULL
|
click
|
ocr
|
NULL
|
PhostormINavigarecodeFV faVsco.jsProiect© TrackRec PhostormINavigarecodeFV faVsco.jsProiect© TrackRecordingFileSiz© TrackRecordingSizeEnT. ValidateSmitProspect:AjReports0 CalendarConference0 Crm> @ Bullhorn>O CloseC Copper>J Crmobiects07 DecorateActivitv• Dummy) Helpersv D HubspotAccountSyncStrate>D Actionsn ContactsuncStrateM Fields• M lournal1 Metadatalv OpportunitySyncSti>MConcerns.(c) Hubsnotl actMonC HubspotLastMor(C) Hubsnotl actMou© HubspotLastMo(C) Hubsnotl actMou© HubspotSingleS© HubspotSyncStr© HubspotWebhoo~ M Padination© HubspotPaginatil© PaginationConfi(C) PaqinationState.> D ProspectSearchStr:› D Redisv D ServiceTraits() OpportunitvSvnc() SvncCrmEntitiesT SuncFieldstirait.T. WriteCrmTrait.o• M UtilsM Webhook(C) Hubspot/Service.pho© Companies.php(C) MatchActivityermData.pho(C) CrmActivityService.php(C) CachedCrmServiceDecorator.php* Hubspot/.../SyncCrmEntitiesTrait.php©) Pipedrive/Service.php0 Servicelntertace.php@' OpportunitvSvncTest.ohp(C) RateLimit.oho© ProviderRateLimiter.phpcllass Uuient extends Basedlient imoilements Huhsnotu ientinterfaceA2 A68 V2^nrivate function executeRequest(callable Sanicallal114115IspotkateL1m1t Ihrowable se: booustsse.method: 'qetCode') && (int) Se->qetCode0 === 429:RetrvAfterThrowable Se): intAse.'aetResnonseHeadens')) $->detResnonseleadensor?:iupport \Facades\Log::channel('custom_channel')->info('$headers' . PHP_EOL • print_r(Sheaders, true));ders| 'Retry-Aften'] 22 Sheaders"'retry-aften! 22 null.$value)) {Svaluel0l 22 null.134cCvalue)))dInt) Svalne•13613714€142 Ct› .nimumApiVersion(: string{...}147 Gt › Istance@: Factoryf...}C) BatchSvncCollectot 1c/ t:wInstance@: Discovervf...}c) RatchSvncRedisSec) Client nhoC) ClocedDea|Stadecs1 Limits for Hubspot APT@ DealFieldsService r .19narAuhe for IdE suadestiions Detect more seamritvlisaues in vour D.Dfflles llia SonarAube Claud for free //lDownload SonarOnbe Server Illear more /llDonit ask adain /today 1052514 HS_local jiminny@localhostiti accounts (jiminny@localhost]# concole [STAGING1A console [PKOU.365367369371-382=385=387=389392393394397/ 399401|26-05-07 12:57:19 Local.NOTICE: Monitoring start{"correlation_id":"4c2d4775-716d-4Ca6-b94d-Cb17 m26-05-07 12:57:191 local. NOTICE: Monitoring endX971 A V26-05-07 12:57:22) Local.INF0: Jiminny Console \Commands \Command::run Memory usage before starting command ¿"comma26-05-07 12:57:22Jfor command 1"command": "mailbox(26-05-07 12:57:25) local.INF0: Jiminny Console\Commands\Command::run Memory usage before starting command 1"comma26-05-07 12:57:25Jlocal.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"s {"correlation_id":126-05-07 12:57:25 Loc0L. INF0: EmailSchedulel FINISHEd batch orocess "host"*"docker Lamo 1" "orocessed":0r *"co(26-05-07 12:57:25) local.INF0: Jiminny Console\Commands \Command::run Memory usagefor command 1"command":"mailbox126-05-07 12257-22D0cLNSO Jaiminny Consolle kommands Vommande enun Memony usade hefone stantino command "comma26-05-07 12:57:27) local.INF0: [EmailSchedule] STARTING batch create {"host":"ker_lamp_1"} {"correlation_id":"26-05-07 12:57:27] local.INF0: [EmailSchedule] FINISHED batch create {"host":"docker_lamp1"z &"cornplation id".".26-05-07 12:57:27] local.INF0: Jiminny\Console\Commands\Command::run Memory usagefor command {"command": "mailbox26-05-07 12:57:28] local.INF0: [Jiminny\Jobs \Mailbox\CreateBatches] processed 2 inboxes and created 0 batches {"us26-05-07 12:58:06] local.INF0: [SocialAccountService) Fetching token {"socialAccountId":1499,"provider":"hubspot"]26-05-07 12:58:06] local.INF0: [SocialAccountService) Token retrieved {"socialAccountId":1499,"provider":"hubspot'26-05-07 12:58:06] local.INF0: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_ic26-05-07 12:58:06] local.INF0: [Crm0wnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot26-05-07 12:58:06] local.ERROR: Client error:POST https://api.hubapi.com/crm/v3/objects/contact/search*resultectatus":"error" "message":"You have reached your secondly limit." "errorType":"RATE LIMIT" "correlationId":"019e02€exception":" obnect sevenshores Hubspot Exceptions Badkequest code:429): Client error: 'POST https://api.huhome/J1m1nny/vendor/hubspot/nubspot-php/src/exceptions/Hubspottxcept1on.pnp:24Inome/aaminny/vendor/nubspor/nubspor-oho/sccirco/ulnentonous: sevenshoresWuospor exceocions Wunsnorexceni/home/iiminny/app/Services/Crm/Hubspot/Paqination/HubspotPaqinationService.oho(163): SevenShores||Hubspot\\Httpl\(home//iiminny/aop/Services/crm/Hubsoot/Paqination/HubsootPaqinationService.ono/51: Jiminnv ServicesCrmHubso/home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPagin/home//Timinny/aop/Services/crm/Hubsoot/Client.ono/15): JiminnvServicesCrmHubspotCuient->oetPaqinatedDatahome/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny(Services\\Crm\\Hubspot|\Client->getPaginatedDaThome/aliminny/laon/console/Commands/AaminnyDebudcommand.nho./6%lliminnyServicesViom HubsnotSenvice-SmatichB/home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\Console\\Commands|JiminnyDebugCommand->home/~iminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.nhn(36):JiminnvConsoleCommands/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod:home/iiminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.ohn(96)• TlluminateContainenUtilhome /iiminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.ohn(35)• TlluminateContainenBounhome /iiminny/vendor/laravel/framework/soc/Tlluminate/Container/Containen.ohn 799)• TlluminateContainen Round/home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container/home/jiminnv/vendon/cvmfonv/concole/Command/Commandnhn(3/1)• Tlluminato|Concole||Command-seyecute(0hzect/Svmf/home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Comn/home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\Console\Command->run(Object (Symfony\Con/home/jiminny/vendor/symfony/console/Application.php(356): Symfony\Component)\Console\Application->doRunCommanc/home/jiminny/vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun(0biect/home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Cor/home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\Foundation\(/home/jiminny/artisan(13): Illuminatel(Foundation\Application->handleCommand(Obiect(Symfony)\Componentl\Console){main?evious excentionobnect(GuzzleHttp|\Exception|\ClientException(code: 429): Client error: 'POST httos://aoi.hu• Lukas sterka 121 • In ih 12mU AskJiminnyReportActivityServiceTest vCascadeHubspot Rate LimitingHubSpot Rate Limit HHow to Access the Header in Your CodeIt you need to check the header manually for debugging:"phpFor new SDK (Ap1Except1on)try{Sresponse = Sclient->request(...):} catch (\HubSpot\Client\Crm\Objects\ApiException $e) 1Sheaders = $e->getResponseHeaders() ?: []:SretryAfter = Sheaders 'Retry-Atter'10 ?? Sheaders "retry-after' 0 7? nuut:if (SretryAfter) {sent retry guidancesteepttanosrethyatcer),I No header - use default hased on error meccadeSbody = ison decode(Se->getResponseBody(), true):SretryAftercvName'] 22 null) {"TEN SELUNDLT_KULLING →> 10,"SECONDLY => 1.default = 10.RecommendationThe current imolementation at Service.pho: 1721-1727 already handles this correctly by checkina policvName :^ oho$response = json_decode($e->getResponseBody(), true);sretryAtter =isset (Sresponse['policvName'] )Sc Sresnonsef'nolicvame'1 ==self.-TEN SECONDLY ROLLING POLTC? self::TEN SECONDLY ROLLING LIMIT# 10 coconde: 1; // Default 1 second for other limitsTo see if headers are actually present, add temporary logging:• php$headers = $e->getResponseHeaders() ?: []:Loa: :debua("[HubSpot) Rate limit response headers'. ['headersi = Cheaderç.'retry after' = Sheaders ['Retry-After'] ?? Sheaders('retry-after'] ?? 'NOT_ PRESENT'.100% 12Thu 7 May 16:18:17+0 ..Gal .Ask anvthina (&4D< CodeC° AdantiveWN Windsurf Teams120-127UTC.8io 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4218
|
151
|
6
|
2026-05-07T13:18:12.312206+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159892312_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
633
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.55,"average_seconds_per_request":0.55} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring start {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.51,"average_seconds_per_request":0.51} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring end {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.62,"average_seconds_per_request":0.62} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.78,"average_seconds_per_request":0.78} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":1.21,"average_seconds_per_request":1.21} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.53,"average_seconds_per_request":0.53} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:32] local.INFO: [Jiminny\Jobs\Mailbox\CreateBatches] processed 2 inboxes and created 0 batches {"userId":null,"batchSize":30,"maxBatches":1000} {"correlation_id":"92242bd6-7014-4487-a50b-1570e1a88e7a","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring start {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring end {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring start {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring end {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:18] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {"team_id":1,"reason":"{\"message\":\"Forbidden\"}"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {"options":{"from":null,"to":null,"help":false,"silent":false,"quiet":false,"verbose":false,"version":false,"ansi":null,"no-interaction":false,"env":null}} {"correlation_id":"825ef2d7-b5f8-45cd-b19d-20a179b06934","trace_id":"5825a6c8-14c9-4bec-b688-d4895cfc41cc"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring start {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring end {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:50","to":"12:55"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:45","to":"02:50"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:57:40.609671Z"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring start {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring end {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:35] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {"host":"docker_lamp_1"} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {"host":"docker_lamp_1","events":2} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {"expires_in":1800,"cached_for":1500} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {"runtime_seconds":57,"total_cycles":5,"files_downloaded":0,"empty_files":0,"other_portal_skipped":0,"total_events":0,"events_per_file":0,"avg_api_ms":238.3,"avg_download_ms":0.0,"avg_transform_ms":0.0,"avg_process_ms":0.0,"peak_memory_mb":99.73} {"correlation_id"...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"633","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.55,\"average_seconds_per_request\":0.55} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring start {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.51,\"average_seconds_per_request\":0.51} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring end {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.62,\"average_seconds_per_request\":0.62} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.78,\"average_seconds_per_request\":0.78} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":1.21,\"average_seconds_per_request\":1.21} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.53,\"average_seconds_per_request\":0.53} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:32] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"92242bd6-7014-4487-a50b-1570e1a88e7a\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring start {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring end {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring start {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring end {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {\"team_id\":1,\"reason\":\"{\\\"message\\\":\\\"Forbidden\\\"}\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {\"options\":{\"from\":null,\"to\":null,\"help\":false,\"silent\":false,\"quiet\":false,\"verbose\":false,\"version\":false,\"ansi\":null,\"no-interaction\":false,\"env\":null}} {\"correlation_id\":\"825ef2d7-b5f8-45cd-b19d-20a179b06934\",\"trace_id\":\"5825a6c8-14c9-4bec-b688-d4895cfc41cc\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring start {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring end {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:50\",\"to\":\"12:55\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:45\",\"to\":\"02:50\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:57:40.609671Z\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring start {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring end {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {\"host\":\"docker_lamp_1\",\"events\":2} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":57,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":238.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:50] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":37119,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"902cef33-4733-4b2a-9693-affb8645cecc\",\"trace_id\":\"4ffe2bb8-67c6-422a-a846-319973cc0259\"}\n[2026-05-07 12:56:50] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":23195976,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 59 due to unauthorized access to the mailbox {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 212 due to unauthorized access to the mailbox {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.3,\"average_seconds_per_request\":0} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":1854.64,\"usage\":24199288,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25235152,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":70.53,\"usage\":25225384,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25263936,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"33e34a7a-1c02-4f04-87ac-22c3a385e6e3\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":306,\"sociable_id\":109,\"provider_user_id\":\"11348452\",\"expires\":1701077403,\"refresh_token_expires\":null,\"provider\":\"hubspot\",\"state\":\"full-refresh\",\"auth_scope\":null,\"retry_after\":null,\"created_at\":\"2020-09-01 16:59:04\",\"updated_at\":\"2023-11-27 09:30:03\"}}} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":47.7,\"usage\":25451952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25490320,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":44.12,\"usage\":25547952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25587032,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.28,\"average_seconds_per_request\":0} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":412.19,\"usage\":25739960,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25172624,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.23,\"average_seconds_per_request\":0} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":291.83,\"usage\":25225088,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:54] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring start {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring end {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:28] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"c296bf83-9f7c-4228-b6f5-99db6040fa01\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.ERROR: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e0284-5 (truncated...)\n {\"exception\":\"[object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#5 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#7 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#14 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#16 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#21 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#22 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#15 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#17 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#24 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#26 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#31 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#32 {main}\n\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring start {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring end {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:36] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.NOTICE: Calendar sync start {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: ef9bb388-453e-4744-a2e1-95e49ced1700 Correlation ID: 3b889c73-f943-4048-ba3b-63ac50581245 Timestamp: 2026-05-07 12:58:53Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:53Z\\\",\\\"trace_id\\\":\\\"ef9bb388-453e-4744-a2e1-95e49ced1700\\\",\\\"correlation_id\\\":\\\"3b889c73-f943-4048-ba3b-63ac50581245\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 0b8181c0-c858-4d17-af69-c23b7f5a0a00 Correlation ID: 2ce9e931-f423-4048-b1d7-ae1910cd4834 Timestamp: 2026-05-07 12:58:54Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:54Z\\\",\\\"trace_id\\\":\\\"0b8181c0-c858-4d17-af69-c23b7f5a0a00\\\",\\\"correlation_id\\\":\\\"2ce9e931-f423-4048-b1d7-ae1910cd4834\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 4f38b1ca-479e-445c-8db5-29366d0a0c00 Correlation ID: d0a4d623-1a23-4fcc-aebf-ccafeed44a92 Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"4f38b1ca-479e-445c-8db5-29366d0a0c00\\\",\\\"correlation_id\\\":\\\"d0a4d623-1a23-4fcc-aebf-ccafeed44a92\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [Calendar] Processing sync {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"from\":null,\"to\":null,\"delta\":\"CIiFh8TP44kDEIiFh8TP44kDGAUgkZvkzgIokZvkzgI=\",\"last_sync\":\"2024-12-09 07:12:53\",\"dateMode\":\"daily\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 1791a948-a974-424b-9246-7fedfa913b00 Correlation ID: b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"1791a948-a974-424b-9246-7fedfa913b00\\\",\\\"correlation_id\\\":\\\"b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 2be27598-8820-475c-b6ca-a30513720c00 Correlation ID: d3ed2a98-4aa9-4a63-819b-d36fd20b8d62 Timestamp: 2026-05-07 12:58:57Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:57Z\\\",\\\"trace_id\\\":\\\"2be27598-8820-475c-b6ca-a30513720c00\\\",\\\"correlation_id\\\":\\\"d3ed2a98-4aa9-4a63-819b-d36fd20b8d62\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"from\":null,\"to\":null,\"delta\":\"CJ_x49O3jpIDEJ_x49O3jpIDGAUgw67KlwMow67KlwM=\",\"last_sync\":\"2026-01-19 07:48:40\",\"dateMode\":\"daily\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Pipedrive] Account not connected for user {\"userId\":\"e6538737-e7b4-455f-a37a-3e79b665a220\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1116,\"sociable_id\":241,\"provider_user_id\":\"19555731\",\"expires\":1775683749,\"refresh_token_expires\":null,\"provider\":\"pipedrive\",\"state\":\"full-refresh\",\"auth_scope\":\"base,deals:full,activities:full,contacts:full,search:read\",\"retry_after\":null,\"created_at\":\"2023-09-08 09:44:29\",\"updated_at\":\"2026-04-08 22:58:34\"}}} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] CRM disconnected for user so events will not be matched {\"provider\":\"pipedrive\",\"user_id\":241,\"message\":\"Your Pipedrive account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\",\"from\":null,\"to\":null,\"delta\":\"R0usmcdvmMuZCBYV0hguCHhwR3crxfEuMI8zGlf-bMYpCFtdxXvSJWTlnqQvu_jjoOrOYL2VG9rZwFHCERHxGfGEK3CmQX6x8MJG3ZbBXGuVIS6C7u-doY5maMRdsfnrHIAEMJd4Bs_WMfMH4tDJ8j9aul7DHDEJaP7w0PoPPpcoxu4nEk4vk-MolJBEgkSrayEewuBs5JVItUX9lUY2tA.yO2roNQ4Vdm6hBgoutuphGchuzbvsk7aqt5wHfcyeFQ\",\"last_sync\":\"2026-05-06 15:58:35\",\"dateMode\":\"daily\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring start {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring end {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring start {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring end {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:29] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:55\",\"to\":\"13:00\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:50\",\"to\":\"02:55\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:39] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T13:02:45.724437Z\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812331,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812332,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812333,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812334,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812335,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812336,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.ALERT: [SyncActivity] Failed {\"import_id\":812331,\"provider\":\"twilio-flex\",\"provider_id\":317,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Social account for Salesforce cannot be found. Please login to Jiminny to connect.\",\"file\":\"/home/jiminny/app/Services/Crm/BaseService.php\",\"line\":646} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.ALERT: [SyncActivity] Failed {\"import_id\":812332,\"provider\":\"xant\",\"provider_id\":161,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812333,\"provider\":\"apollo\",\"provider_id\":441,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812334,\"provider\":\"groove\",\"provider_id\":228,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.ALERT: [SyncActivity] Failed {\"import_id\":812335,\"provider\":\"twilio-video\",\"provider_id\":243,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Start {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:44:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] End {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Memory usage {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27230632,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Dispatching activity sync job {\"import_id\":812337,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SyncActivity] Start {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:00:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] End {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] Memory usage {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27392888,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":56,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":181.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring start {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring end {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"3e2ef780-0c9d-4c30-9dc9-92315055c632\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring start {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring end {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.55,\"average_seconds_per_request\":0.55} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring start {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.51,\"average_seconds_per_request\":0.51} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring end {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.62,\"average_seconds_per_request\":0.62} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.78,\"average_seconds_per_request\":0.78} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":1.21,\"average_seconds_per_request\":1.21} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.53,\"average_seconds_per_request\":0.53} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:32] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"92242bd6-7014-4487-a50b-1570e1a88e7a\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring start {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring end {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring start {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring end {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {\"team_id\":1,\"reason\":\"{\\\"message\\\":\\\"Forbidden\\\"}\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {\"options\":{\"from\":null,\"to\":null,\"help\":false,\"silent\":false,\"quiet\":false,\"verbose\":false,\"version\":false,\"ansi\":null,\"no-interaction\":false,\"env\":null}} {\"correlation_id\":\"825ef2d7-b5f8-45cd-b19d-20a179b06934\",\"trace_id\":\"5825a6c8-14c9-4bec-b688-d4895cfc41cc\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring start {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring end {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:50\",\"to\":\"12:55\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:45\",\"to\":\"02:50\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:57:40.609671Z\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring start {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring end {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {\"host\":\"docker_lamp_1\",\"events\":2} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":57,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":238.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:50] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":37119,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"902cef33-4733-4b2a-9693-affb8645cecc\",\"trace_id\":\"4ffe2bb8-67c6-422a-a846-319973cc0259\"}\n[2026-05-07 12:56:50] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":23195976,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 59 due to unauthorized access to the mailbox {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 212 due to unauthorized access to the mailbox {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.3,\"average_seconds_per_request\":0} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":1854.64,\"usage\":24199288,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25235152,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":70.53,\"usage\":25225384,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25263936,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"33e34a7a-1c02-4f04-87ac-22c3a385e6e3\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":306,\"sociable_id\":109,\"provider_user_id\":\"11348452\",\"expires\":1701077403,\"refresh_token_expires\":null,\"provider\":\"hubspot\",\"state\":\"full-refresh\",\"auth_scope\":null,\"retry_after\":null,\"created_at\":\"2020-09-01 16:59:04\",\"updated_at\":\"2023-11-27 09:30:03\"}}} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":47.7,\"usage\":25451952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25490320,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":44.12,\"usage\":25547952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25587032,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.28,\"average_seconds_per_request\":0} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":412.19,\"usage\":25739960,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25172624,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.23,\"average_seconds_per_request\":0} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":291.83,\"usage\":25225088,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:54] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring start {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring end {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:28] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"c296bf83-9f7c-4228-b6f5-99db6040fa01\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.ERROR: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e0284-5 (truncated...)\n {\"exception\":\"[object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#5 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#7 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#14 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#16 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#21 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#22 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#15 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#17 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#24 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#26 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#31 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#32 {main}\n\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring start {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring end {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:36] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.NOTICE: Calendar sync start {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: ef9bb388-453e-4744-a2e1-95e49ced1700 Correlation ID: 3b889c73-f943-4048-ba3b-63ac50581245 Timestamp: 2026-05-07 12:58:53Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:53Z\\\",\\\"trace_id\\\":\\\"ef9bb388-453e-4744-a2e1-95e49ced1700\\\",\\\"correlation_id\\\":\\\"3b889c73-f943-4048-ba3b-63ac50581245\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 0b8181c0-c858-4d17-af69-c23b7f5a0a00 Correlation ID: 2ce9e931-f423-4048-b1d7-ae1910cd4834 Timestamp: 2026-05-07 12:58:54Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:54Z\\\",\\\"trace_id\\\":\\\"0b8181c0-c858-4d17-af69-c23b7f5a0a00\\\",\\\"correlation_id\\\":\\\"2ce9e931-f423-4048-b1d7-ae1910cd4834\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 4f38b1ca-479e-445c-8db5-29366d0a0c00 Correlation ID: d0a4d623-1a23-4fcc-aebf-ccafeed44a92 Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"4f38b1ca-479e-445c-8db5-29366d0a0c00\\\",\\\"correlation_id\\\":\\\"d0a4d623-1a23-4fcc-aebf-ccafeed44a92\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [Calendar] Processing sync {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"from\":null,\"to\":null,\"delta\":\"CIiFh8TP44kDEIiFh8TP44kDGAUgkZvkzgIokZvkzgI=\",\"last_sync\":\"2024-12-09 07:12:53\",\"dateMode\":\"daily\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 1791a948-a974-424b-9246-7fedfa913b00 Correlation ID: b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"1791a948-a974-424b-9246-7fedfa913b00\\\",\\\"correlation_id\\\":\\\"b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 2be27598-8820-475c-b6ca-a30513720c00 Correlation ID: d3ed2a98-4aa9-4a63-819b-d36fd20b8d62 Timestamp: 2026-05-07 12:58:57Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:57Z\\\",\\\"trace_id\\\":\\\"2be27598-8820-475c-b6ca-a30513720c00\\\",\\\"correlation_id\\\":\\\"d3ed2a98-4aa9-4a63-819b-d36fd20b8d62\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"from\":null,\"to\":null,\"delta\":\"CJ_x49O3jpIDEJ_x49O3jpIDGAUgw67KlwMow67KlwM=\",\"last_sync\":\"2026-01-19 07:48:40\",\"dateMode\":\"daily\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Pipedrive] Account not connected for user {\"userId\":\"e6538737-e7b4-455f-a37a-3e79b665a220\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1116,\"sociable_id\":241,\"provider_user_id\":\"19555731\",\"expires\":1775683749,\"refresh_token_expires\":null,\"provider\":\"pipedrive\",\"state\":\"full-refresh\",\"auth_scope\":\"base,deals:full,activities:full,contacts:full,search:read\",\"retry_after\":null,\"created_at\":\"2023-09-08 09:44:29\",\"updated_at\":\"2026-04-08 22:58:34\"}}} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] CRM disconnected for user so events will not be matched {\"provider\":\"pipedrive\",\"user_id\":241,\"message\":\"Your Pipedrive account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\",\"from\":null,\"to\":null,\"delta\":\"R0usmcdvmMuZCBYV0hguCHhwR3crxfEuMI8zGlf-bMYpCFtdxXvSJWTlnqQvu_jjoOrOYL2VG9rZwFHCERHxGfGEK3CmQX6x8MJG3ZbBXGuVIS6C7u-doY5maMRdsfnrHIAEMJd4Bs_WMfMH4tDJ8j9aul7DHDEJaP7w0PoPPpcoxu4nEk4vk-MolJBEgkSrayEewuBs5JVItUX9lUY2tA.yO2roNQ4Vdm6hBgoutuphGchuzbvsk7aqt5wHfcyeFQ\",\"last_sync\":\"2026-05-06 15:58:35\",\"dateMode\":\"daily\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring start {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring end {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring start {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring end {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:29] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:55\",\"to\":\"13:00\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:50\",\"to\":\"02:55\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:39] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T13:02:45.724437Z\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812331,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812332,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812333,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812334,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812335,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812336,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.ALERT: [SyncActivity] Failed {\"import_id\":812331,\"provider\":\"twilio-flex\",\"provider_id\":317,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Social account for Salesforce cannot be found. Please login to Jiminny to connect.\",\"file\":\"/home/jiminny/app/Services/Crm/BaseService.php\",\"line\":646} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.ALERT: [SyncActivity] Failed {\"import_id\":812332,\"provider\":\"xant\",\"provider_id\":161,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812333,\"provider\":\"apollo\",\"provider_id\":441,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812334,\"provider\":\"groove\",\"provider_id\":228,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.ALERT: [SyncActivity] Failed {\"import_id\":812335,\"provider\":\"twilio-video\",\"provider_id\":243,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Start {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:44:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] End {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Memory usage {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27230632,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Dispatching activity sync job {\"import_id\":812337,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SyncActivity] Start {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:00:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] End {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] Memory usage {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27392888,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":56,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":181.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring start {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring end {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"3e2ef780-0c9d-4c30-9dc9-92315055c632\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring start {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring end {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
4314526982584152007
|
6701901348398533693
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
633
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.55,"average_seconds_per_request":0.55} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring start {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.51,"average_seconds_per_request":0.51} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring end {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.62,"average_seconds_per_request":0.62} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.78,"average_seconds_per_request":0.78} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":1.21,"average_seconds_per_request":1.21} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.53,"average_seconds_per_request":0.53} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:32] local.INFO: [Jiminny\Jobs\Mailbox\CreateBatches] processed 2 inboxes and created 0 batches {"userId":null,"batchSize":30,"maxBatches":1000} {"correlation_id":"92242bd6-7014-4487-a50b-1570e1a88e7a","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring start {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring end {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring start {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring end {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:18] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {"team_id":1,"reason":"{\"message\":\"Forbidden\"}"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {"options":{"from":null,"to":null,"help":false,"silent":false,"quiet":false,"verbose":false,"version":false,"ansi":null,"no-interaction":false,"env":null}} {"correlation_id":"825ef2d7-b5f8-45cd-b19d-20a179b06934","trace_id":"5825a6c8-14c9-4bec-b688-d4895cfc41cc"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring start {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring end {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:50","to":"12:55"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:45","to":"02:50"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:57:40.609671Z"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring start {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring end {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:35] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {"host":"docker_lamp_1"} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {"host":"docker_lamp_1","events":2} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {"expires_in":1800,"cached_for":1500} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {"runtime_seconds":57,"total_cycles":5,"files_downloaded":0,"empty_files":0,"other_portal_skipped":0,"total_events":0,"events_per_file":0,"avg_api_ms":238.3,"avg_download_ms":0.0,"avg_transform_ms":0.0,"avg_process_ms":0.0,"peak_memory_mb":99.73} {"correlation_id"...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
4217
|
152
|
5
|
2026-05-07T13:18:10.519083+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159890519_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
633
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.55,"average_seconds_per_request":0.55} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring start {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.51,"average_seconds_per_request":0.51} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring end {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.62,"average_seconds_per_request":0.62} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.78,"average_seconds_per_request":0.78} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":1.21,"average_seconds_per_request":1.21} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.53,"average_seconds_per_request":0.53} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:32] local.INFO: [Jiminny\Jobs\Mailbox\CreateBatches] processed 2 inboxes and created 0 batches {"userId":null,"batchSize":30,"maxBatches":1000} {"correlation_id":"92242bd6-7014-4487-a50b-1570e1a88e7a","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring start {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring end {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring start {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring end {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:18] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {"team_id":1,"reason":"{\"message\":\"Forbidden\"}"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {"options":{"from":null,"to":null,"help":false,"silent":false,"quiet":false,"verbose":false,"version":false,"ansi":null,"no-interaction":false,"env":null}} {"correlation_id":"825ef2d7-b5f8-45cd-b19d-20a179b06934","trace_id":"5825a6c8-14c9-4bec-b688-d4895cfc41cc"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring start {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring end {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:50","to":"12:55"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:45","to":"02:50"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:57:40.609671Z"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring start {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring end {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:35] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {"host":"docker_lamp_1"} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {"host":"docker_lamp_1","events":2} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {"expires_in":1800,"cached_for":1500} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {"runtime_seconds":57,"total_cycles":5,"files_downloaded":0,"empty_files":0,"other_portal_skipped":0,"total_events":0,"events_per_file":0,"avg_api_ms":238.3,"avg_download_ms":0.0,"avg_transform_ms":0.0,"avg_process_ms":0.0,"peak_memory_mb":99.73} {"correlation_id"...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"bounds":{"left":0.39926863,"top":0.105347164,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.4119016,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"bounds":{"left":0.42287233,"top":0.10454908,"width":0.043882977,"height":0.015961692},"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.47573137,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"bounds":{"left":0.48570478,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"bounds":{"left":0.4943484,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"bounds":{"left":0.50299203,"top":0.10454908,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.27027926,"top":1.0,"width":0.00731383,"height":0.0},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"bounds":{"left":0.51662236,"top":0.103751,"width":0.025598405,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.5422208,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"bounds":{"left":0.55086434,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"bounds":{"left":0.55950797,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"bounds":{"left":0.5681516,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.6988032,"top":0.10295291,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"633","depth":4,"bounds":{"left":0.6831782,"top":0.13407822,"width":0.012632979,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.6974734,"top":0.13248204,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.70478725,"top":0.13248204,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.55,\"average_seconds_per_request\":0.55} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring start {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.51,\"average_seconds_per_request\":0.51} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring end {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.62,\"average_seconds_per_request\":0.62} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.78,\"average_seconds_per_request\":0.78} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":1.21,\"average_seconds_per_request\":1.21} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.53,\"average_seconds_per_request\":0.53} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:32] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"92242bd6-7014-4487-a50b-1570e1a88e7a\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring start {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring end {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring start {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring end {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {\"team_id\":1,\"reason\":\"{\\\"message\\\":\\\"Forbidden\\\"}\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {\"options\":{\"from\":null,\"to\":null,\"help\":false,\"silent\":false,\"quiet\":false,\"verbose\":false,\"version\":false,\"ansi\":null,\"no-interaction\":false,\"env\":null}} {\"correlation_id\":\"825ef2d7-b5f8-45cd-b19d-20a179b06934\",\"trace_id\":\"5825a6c8-14c9-4bec-b688-d4895cfc41cc\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring start {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring end {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:50\",\"to\":\"12:55\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:45\",\"to\":\"02:50\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:57:40.609671Z\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring start {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring end {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {\"host\":\"docker_lamp_1\",\"events\":2} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":57,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":238.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:50] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":37119,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"902cef33-4733-4b2a-9693-affb8645cecc\",\"trace_id\":\"4ffe2bb8-67c6-422a-a846-319973cc0259\"}\n[2026-05-07 12:56:50] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":23195976,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 59 due to unauthorized access to the mailbox {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 212 due to unauthorized access to the mailbox {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.3,\"average_seconds_per_request\":0} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":1854.64,\"usage\":24199288,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25235152,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":70.53,\"usage\":25225384,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25263936,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"33e34a7a-1c02-4f04-87ac-22c3a385e6e3\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":306,\"sociable_id\":109,\"provider_user_id\":\"11348452\",\"expires\":1701077403,\"refresh_token_expires\":null,\"provider\":\"hubspot\",\"state\":\"full-refresh\",\"auth_scope\":null,\"retry_after\":null,\"created_at\":\"2020-09-01 16:59:04\",\"updated_at\":\"2023-11-27 09:30:03\"}}} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":47.7,\"usage\":25451952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25490320,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":44.12,\"usage\":25547952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25587032,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.28,\"average_seconds_per_request\":0} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":412.19,\"usage\":25739960,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25172624,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.23,\"average_seconds_per_request\":0} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":291.83,\"usage\":25225088,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:54] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring start {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring end {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:28] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"c296bf83-9f7c-4228-b6f5-99db6040fa01\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.ERROR: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e0284-5 (truncated...)\n {\"exception\":\"[object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#5 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#7 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#14 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#16 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#21 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#22 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#15 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#17 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#24 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#26 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#31 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#32 {main}\n\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring start {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring end {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:36] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.NOTICE: Calendar sync start {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: ef9bb388-453e-4744-a2e1-95e49ced1700 Correlation ID: 3b889c73-f943-4048-ba3b-63ac50581245 Timestamp: 2026-05-07 12:58:53Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:53Z\\\",\\\"trace_id\\\":\\\"ef9bb388-453e-4744-a2e1-95e49ced1700\\\",\\\"correlation_id\\\":\\\"3b889c73-f943-4048-ba3b-63ac50581245\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 0b8181c0-c858-4d17-af69-c23b7f5a0a00 Correlation ID: 2ce9e931-f423-4048-b1d7-ae1910cd4834 Timestamp: 2026-05-07 12:58:54Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:54Z\\\",\\\"trace_id\\\":\\\"0b8181c0-c858-4d17-af69-c23b7f5a0a00\\\",\\\"correlation_id\\\":\\\"2ce9e931-f423-4048-b1d7-ae1910cd4834\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 4f38b1ca-479e-445c-8db5-29366d0a0c00 Correlation ID: d0a4d623-1a23-4fcc-aebf-ccafeed44a92 Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"4f38b1ca-479e-445c-8db5-29366d0a0c00\\\",\\\"correlation_id\\\":\\\"d0a4d623-1a23-4fcc-aebf-ccafeed44a92\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [Calendar] Processing sync {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"from\":null,\"to\":null,\"delta\":\"CIiFh8TP44kDEIiFh8TP44kDGAUgkZvkzgIokZvkzgI=\",\"last_sync\":\"2024-12-09 07:12:53\",\"dateMode\":\"daily\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 1791a948-a974-424b-9246-7fedfa913b00 Correlation ID: b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"1791a948-a974-424b-9246-7fedfa913b00\\\",\\\"correlation_id\\\":\\\"b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 2be27598-8820-475c-b6ca-a30513720c00 Correlation ID: d3ed2a98-4aa9-4a63-819b-d36fd20b8d62 Timestamp: 2026-05-07 12:58:57Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:57Z\\\",\\\"trace_id\\\":\\\"2be27598-8820-475c-b6ca-a30513720c00\\\",\\\"correlation_id\\\":\\\"d3ed2a98-4aa9-4a63-819b-d36fd20b8d62\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"from\":null,\"to\":null,\"delta\":\"CJ_x49O3jpIDEJ_x49O3jpIDGAUgw67KlwMow67KlwM=\",\"last_sync\":\"2026-01-19 07:48:40\",\"dateMode\":\"daily\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Pipedrive] Account not connected for user {\"userId\":\"e6538737-e7b4-455f-a37a-3e79b665a220\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1116,\"sociable_id\":241,\"provider_user_id\":\"19555731\",\"expires\":1775683749,\"refresh_token_expires\":null,\"provider\":\"pipedrive\",\"state\":\"full-refresh\",\"auth_scope\":\"base,deals:full,activities:full,contacts:full,search:read\",\"retry_after\":null,\"created_at\":\"2023-09-08 09:44:29\",\"updated_at\":\"2026-04-08 22:58:34\"}}} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] CRM disconnected for user so events will not be matched {\"provider\":\"pipedrive\",\"user_id\":241,\"message\":\"Your Pipedrive account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\",\"from\":null,\"to\":null,\"delta\":\"R0usmcdvmMuZCBYV0hguCHhwR3crxfEuMI8zGlf-bMYpCFtdxXvSJWTlnqQvu_jjoOrOYL2VG9rZwFHCERHxGfGEK3CmQX6x8MJG3ZbBXGuVIS6C7u-doY5maMRdsfnrHIAEMJd4Bs_WMfMH4tDJ8j9aul7DHDEJaP7w0PoPPpcoxu4nEk4vk-MolJBEgkSrayEewuBs5JVItUX9lUY2tA.yO2roNQ4Vdm6hBgoutuphGchuzbvsk7aqt5wHfcyeFQ\",\"last_sync\":\"2026-05-06 15:58:35\",\"dateMode\":\"daily\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring start {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring end {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring start {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring end {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:29] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:55\",\"to\":\"13:00\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:50\",\"to\":\"02:55\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:39] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T13:02:45.724437Z\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812331,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812332,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812333,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812334,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812335,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812336,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.ALERT: [SyncActivity] Failed {\"import_id\":812331,\"provider\":\"twilio-flex\",\"provider_id\":317,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Social account for Salesforce cannot be found. Please login to Jiminny to connect.\",\"file\":\"/home/jiminny/app/Services/Crm/BaseService.php\",\"line\":646} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.ALERT: [SyncActivity] Failed {\"import_id\":812332,\"provider\":\"xant\",\"provider_id\":161,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812333,\"provider\":\"apollo\",\"provider_id\":441,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812334,\"provider\":\"groove\",\"provider_id\":228,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.ALERT: [SyncActivity] Failed {\"import_id\":812335,\"provider\":\"twilio-video\",\"provider_id\":243,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Start {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:44:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] End {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Memory usage {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27230632,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Dispatching activity sync job {\"import_id\":812337,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SyncActivity] Start {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:00:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] End {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] Memory usage {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27392888,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":56,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":181.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring start {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring end {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"3e2ef780-0c9d-4c30-9dc9-92315055c632\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring start {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring end {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fa8a3008-d298-4682-bbbc-fdc77520e0d7\",\"trace_id\":\"7cfb2afb-9fc4-4a77-81be-65dce93c7d80\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"932ced9d-9804-48ed-976a-1f8bf5e75707\",\"trace_id\":\"21bf320c-58f3-4082-831d-9f07f6c6a669\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.55,\"average_seconds_per_request\":0.55} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring start {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.51,\"average_seconds_per_request\":0.51} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:18] local.NOTICE: Monitoring end {\"correlation_id\":\"ae3ec78f-432c-4e22-b73b-0413af73d9f3\",\"trace_id\":\"c2feb517-0f2b-4ad9-bce5-4d57476a164b\"}\n[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2bf2f73f-007c-4909-925e-f1749fbf87b3\",\"trace_id\":\"8429123c-d92c-48d9-a154-29bc0aa0e2a1\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.48,\"average_seconds_per_request\":0.48} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.62,\"average_seconds_per_request\":0.62} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.78,\"average_seconds_per_request\":0.78} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":1.21,\"average_seconds_per_request\":1.21} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/contact/search\",\"total_requests\":1,\"total_records_fetched\":1,\"total_elapsed_seconds\":0.53,\"average_seconds_per_request\":0.53} {\"correlation_id\":\"84c9b84a-9f60-4e35-956a-ead94112d174\",\"trace_id\":\"07a542c8-266e-40e4-97ec-725d0fd3192d\"}\n[2026-05-07 12:52:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8\",\"trace_id\":\"64ccac6b-34f7-45ed-a8ac-b63adbb19107\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6e1a36d0-a87a-455f-88b9-04f16718ea33\",\"trace_id\":\"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:31] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"80549428-beea-4a6c-97d3-818ca0f059f3\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:32] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"92242bd6-7014-4487-a50b-1570e1a88e7a\",\"trace_id\":\"55ddd59b-073b-4331-8cdb-baa869dcff70\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:52:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d467eace-3254-4ecc-8d8e-a94688d6d3ad\",\"trace_id\":\"5105ca8f-3c0d-4798-b748-5a7d6fbd7531\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"04363b29-2f82-470a-89d0-c5ce4f4779d7\",\"trace_id\":\"3c76a1f1-3348-4e2b-897c-4a216ca95147\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:11] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5ebbecd0-866c-443f-965f-b6ac03735379\",\"trace_id\":\"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring start {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:18] local.NOTICE: Monitoring end {\"correlation_id\":\"f39f0d3c-a292-41cb-8834-45dae1f8cf47\",\"trace_id\":\"b6e7e2a7-85af-401d-afc6-bec2bdab34d7\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"419bb747-2669-496f-944b-1073496cc271\",\"trace_id\":\"4cb913a4-ef75-422b-80eb-fbfb988521ed\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f4805c97-9344-4111-8be2-2b1efeae07bb\",\"trace_id\":\"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:53:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f\",\"trace_id\":\"75f27a23-2021-41a5-9e5f-4b1cb4f143a6\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ad151521-f676-4351-a70b-f44dc0b94990\",\"trace_id\":\"17e39c4c-85cb-49a4-815e-b7315a8c2249\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"ed0583cf-03c6-4696-b859-876c8efa4473\",\"trace_id\":\"3f9e0a3c-2178-4885-95eb-8618b8cfc042\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring start {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:10] local.NOTICE: Monitoring end {\"correlation_id\":\"7142250a-b897-4620-8ff7-fd9b3a1f3802\",\"trace_id\":\"597def1e-ca38-4cc4-8890-fdcd5baff948\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d\",\"trace_id\":\"73937bdc-10b9-4508-9ef2-86420fe774fc\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8f1d8932-2839-4256-99ab-1fd13e8381c6\",\"trace_id\":\"cc090767-edc2-4a89-90c2-116f1737de7f\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9d324c6d-5b36-46ee-89c6-f95f86bf3f39\",\"trace_id\":\"860cdff0-9356-4e94-84cc-e011a74ba56c\"}\n[2026-05-07 12:54:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1496,\"provider\":\"aircall\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {\"team_id\":1,\"reason\":\"{\\\"message\\\":\\\"Forbidden\\\"}\"} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:aircall:check-and-renew\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c2009a88-eea6-4954-8642-ef5d9cb56b42\",\"trace_id\":\"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab\"}\n[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {\"options\":{\"from\":null,\"to\":null,\"help\":false,\"silent\":false,\"quiet\":false,\"verbose\":false,\"version\":false,\"ansi\":null,\"no-interaction\":false,\"env\":null}} {\"correlation_id\":\"825ef2d7-b5f8-45cd-b19d-20a179b06934\",\"trace_id\":\"5825a6c8-14c9-4bec-b688-d4895cfc41cc\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c0dc8e25-7a51-4023-be61-d0abd6d72e37\",\"trace_id\":\"16b8fa3e-92b1-465e-82d4-642a2d14c7c5\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1c65fdd1-1f79-435d-b469-add46ddafd63\",\"trace_id\":\"62f2a3bb-3be7-4c76-a9dd-222bfb895fab\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring start {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:11] local.NOTICE: Monitoring end {\"correlation_id\":\"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55\",\"trace_id\":\"e75cb5c6-6dd8-4000-8d26-4418020c7cfe\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dba5c474-4d40-44da-baf2-f8b30db9a2f5\",\"trace_id\":\"adb45622-1fb0-457c-bf20-8dcceab2d62a\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"22c96a8e-4424-4a1f-b349-206276eefe4c\",\"trace_id\":\"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5f958e8d-1d01-4144-abd6-2513e5524ad3\",\"trace_id\":\"828bc5b7-e2aa-4443-901f-38dd94bb7cc5\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a\",\"trace_id\":\"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c5dd8132-d7e1-4caa-84d1-0a50d02df8da\",\"trace_id\":\"bc7341c5-b8e2-48ea-9670-7ec375363180\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0\",\"trace_id\":\"efb1619f-4185-4319-9bfb-305cee0b6bfc\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:50\",\"to\":\"12:55\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:45\",\"to\":\"02:50\"} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3792b31a-080a-4fe4-9823-5602361325ba\",\"trace_id\":\"41a2fde1-48f6-4667-84b7-a2f93e9ad2da\"}\n[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"e31362f8-5362-478d-911d-099b61f96cd2\",\"trace_id\":\"2587b5d0-6bef-40a5-afd5-a15003b7cf95\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e676ae4-5d63-49d4-9001-559088adf06b\",\"trace_id\":\"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:57:40.609671Z\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1f830896-8142-41d1-bfc9-4cbb9179ffda\",\"trace_id\":\"e348a096-7f37-4308-a6d8-66131e8be901\"}\n[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2d8b30b4-87aa-480f-9b9e-5a9c709b742a\",\"trace_id\":\"25b7be6c-1faf-430b-a724-a4ff28773a31\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"efd336d7-db4d-459e-b6e7-bf73454e955e\",\"trace_id\":\"0a82c3d5-0417-48c8-b88f-70ec33e2326a\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring start {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:12] local.NOTICE: Monitoring end {\"correlation_id\":\"68481576-8ca6-4ee5-821b-07374702971d\",\"trace_id\":\"c73eac09-5d20-425f-9c22-bd6c65fc60c9\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24\",\"trace_id\":\"f688cd98-c171-4e30-8c72-afc14f040861\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f01636a9-4059-4ab0-9ad2-b078d42cedbd\",\"trace_id\":\"fea938d8-aedc-40ec-b8c2-2f487e1ac808\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":60.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d4558901-264d-4238-8589-62a137bac1fd\",\"trace_id\":\"38e6b5dc-ebd6-46a7-8224-7374d4e58630\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:sync-hubspot-objects\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:26] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:notify-not-logged\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2541e0fa-1117-4863-9523-d723b5821a24\",\"trace_id\":\"d9600320-5133-4938-bdd1-2256dfdf8db4\"}\n[2026-05-07 12:56:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {\"host\":\"docker_lamp_1\",\"events\":2} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"e444f776-37db-4c6d-b30e-20b01a089de7\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":57,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":238.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"fa65a15d-da5b-4c86-ae85-c16937786996\",\"trace_id\":\"7e655fe3-04eb-4a0f-b056-eb64e9c75a80\"}\n[2026-05-07 12:56:50] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":37119,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"902cef33-4733-4b2a-9693-affb8645cecc\",\"trace_id\":\"4ffe2bb8-67c6-422a-a846-319973cc0259\"}\n[2026-05-07 12:56:50] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":23195976,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 59 due to unauthorized access to the mailbox {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":59} {\"correlation_id\":\"20256b2c-2b69-48f6-bdd3-61d047eb0b0d\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync start {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Inbox service] Skipping METADATA SYNC for inbox 212 due to unauthorized access to the mailbox {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:50] local.INFO: [Sync Mailbox] Sync complete {\"inbox_id\":212} {\"correlation_id\":\"b6c31853-3729-4780-a52b-ebcce17d41b9\",\"trace_id\":\"1168869e-e07c-4702-a046-42fc95a91f6d\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:51] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.3,\"average_seconds_per_request\":0} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":1854.64,\"usage\":24199288,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"ed0ddf67-6a40-4958-913f-a055eee12af4\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25235152,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:52] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":70.53,\"usage\":25225384,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0d3cf2b0-a245-4a83-9bd5-1c5788b85738\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25263936,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"33e34a7a-1c02-4f04-87ac-22c3a385e6e3\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":306,\"sociable_id\":109,\"provider_user_id\":\"11348452\",\"expires\":1701077403,\"refresh_token_expires\":null,\"provider\":\"hubspot\",\"state\":\"full-refresh\",\"auth_scope\":null,\"retry_after\":null,\"created_at\":\"2020-09-01 16:59:04\",\"updated_at\":\"2023-11-27 09:30:03\"}}} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":47.7,\"usage\":25451952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"1e46be79-1db4-4829-b19c-1548141a94e0\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25490320,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":44.12,\"usage\":25547952,\"real_usage\":65011712,\"pid\":37113,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"0da4e096-9534-4a72-bc1f-8e61561d8e37\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25587032,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.28,\"average_seconds_per_request\":0} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":412.19,\"usage\":25739960,\"real_usage\":65011712,\"pid\":37113} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\",\"correlation_id\":\"ccfcef46-d2f0-4646-925b-6f1bf46fd46d\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25172624,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":0,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.23,\"average_seconds_per_request\":0} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:53] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":291.83,\"usage\":25225088,\"real_usage\":65011712,\"pid\":37113} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:56:54] local.ERROR: Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned {\"exception\":\"[object] (TypeError(code: 0): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService::getPaginatedDataGenerator(): Return value must be of type Generator, none returned at /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php:82)\n[stacktrace]\n#0 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'deals', 0, 0, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/OpportunitySyncStrategy/HubspotSyncStrategyBase.php(55): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'deals', 0, 0, NULL)\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(73): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\OpportunitySyncStrategy\\\\HubspotSyncStrategyBase->fetchOpportunities(Array, 0, NULL)\n#3 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(118): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunities(Array)\n#4 /home/jiminny/app/Jobs/Crm/SyncHubspotObjects.php(86): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->syncHubspotCrmObjects(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service), Object(Illuminate\\\\Support\\\\Carbon))\n#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects->handle(Object(Jiminny\\\\Services\\\\ResolveTeamCrmConnection), Object(Illuminate\\\\Log\\\\LogManager), Object(Jiminny\\\\Repositories\\\\TeamRepository))\n#6 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#7 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\\\\Container\\\\Container->call(Array)\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Bus\\\\Dispatcher->Illuminate\\\\Bus\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#14 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(136): Illuminate\\\\Bus\\\\Dispatcher->dispatchNow(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects), false)\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\\\Queue\\\\CallQueuedHandler->Illuminate\\\\Queue\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\\\Pipeline\\\\Pipeline->Illuminate\\\\Pipeline\\\\{closure}(Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#17 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(129): Illuminate\\\\Pipeline\\\\Pipeline->then(Object(Closure))\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\\\Queue\\\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Jiminny\\\\Jobs\\\\Crm\\\\SyncHubspotObjects))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\\\Queue\\\\CallQueuedHandler->call(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Array)\n#20 /home/jiminny/app/Queue/Worker/Worker.php(71): Illuminate\\\\Queue\\\\Jobs\\\\Job->fire()\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(435): Jiminny\\\\Queue\\\\Worker\\\\Worker->process('redis', Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\\\\Queue\\\\Worker->runJob(Object(Illuminate\\\\Queue\\\\Jobs\\\\RedisJob), 'redis', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\\\\Queue\\\\Worker->daemon('redis', 'crm-sync,crm-up...', Object(Illuminate\\\\Queue\\\\WorkerOptions))\n#24 /home/jiminny/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->runWorker('redis', 'crm-sync,crm-up...')\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\\\Queue\\\\Console\\\\WorkCommand->handle()\n#26 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#27 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#28 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#31 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#32 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#33 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#34 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Illuminate\\\\Queue\\\\Console\\\\WorkCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#35 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#36 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#37 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#38 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#39 {main}\n\"} {\"correlation_id\":\"eb2b7ebe-9423-4dbc-a38b-e01816fd6aea\",\"trace_id\":\"ba7f9eee-8dcb-4c94-acb0-18f9363757ad\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"854299be-d77a-48bc-870c-b78333916d69\",\"trace_id\":\"89c1eb6c-bc78-419c-9304-b770093d5692\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:16] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e512a3-a227-4569-bcd2-3258a9142d46\",\"trace_id\":\"016bf668-6712-4c0f-8c8c-c2e411a37889\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring start {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:19] local.NOTICE: Monitoring end {\"correlation_id\":\"4c2d4775-716d-4ca6-b94d-cb17dace29a7\",\"trace_id\":\"e969e10d-e5f0-44c6-9767-97a70e05cfe5\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:22] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d03e9546-bfd0-44c6-84ee-299b1e6c14a2\",\"trace_id\":\"acbab6e5-17fc-4b11-907d-ff87322285d7\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a2c0095a-18b2-427e-825b-c68c9dbf63a1\",\"trace_id\":\"9b170d6a-ed10-4a41-af79-684c99021967\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c4e70056-ceab-4c44-874a-8042963ce3ea\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:57:28] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"c296bf83-9f7c-4228-b6f5-99db6040fa01\",\"trace_id\":\"011a70aa-ebb2-4ca8-aef6-4b4cca233da7\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:06] local.ERROR: Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your secondly limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\":\"019e0284-5 (truncated...)\n {\"exception\":\"[object] (SevenShores\\\\Hubspot\\\\Exceptions\\\\BadRequest(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/hubspot/hubspot-php/src/Exceptions/HubspotException.php:24)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(125): SevenShores\\\\Hubspot\\\\Exceptions\\\\HubspotException::create(Object(GuzzleHttp\\\\Exception\\\\ClientException))\n#1 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#2 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#3 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#4 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#5 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#6 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#7 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#9 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#11 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#13 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#14 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#15 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#16 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#17 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#18 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#21 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#22 {main}\n\n[previous exception] [object] (GuzzleHttp\\\\Exception\\\\ClientException(code: 429): Client error: `POST https://api.hubapi.com/crm/v3/objects/contact/search` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your secondly limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\":\\\"019e0284-5 (truncated...)\n at /home/jiminny/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:111)\n[stacktrace]\n#0 /home/jiminny/vendor/guzzlehttp/guzzle/src/Middleware.php(72): GuzzleHttp\\\\Exception\\\\RequestException::create(Object(GuzzleHttp\\\\Psr7\\\\Request), Object(GuzzleHttp\\\\Psr7\\\\Response), NULL, Array, NULL)\n#1 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(209): GuzzleHttp\\\\Middleware::GuzzleHttp\\\\{closure}(Object(GuzzleHttp\\\\Psr7\\\\Response))\n#2 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(158): GuzzleHttp\\\\Promise\\\\Promise::callHandler(1, Object(GuzzleHttp\\\\Psr7\\\\Response), NULL)\n#3 /home/jiminny/vendor/guzzlehttp/promises/src/TaskQueue.php(52): GuzzleHttp\\\\Promise\\\\Promise::GuzzleHttp\\\\Promise\\\\{closure}()\n#4 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(251): GuzzleHttp\\\\Promise\\\\TaskQueue->run(true)\n#5 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(227): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitFn()\n#6 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(272): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#7 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(229): GuzzleHttp\\\\Promise\\\\Promise->invokeWaitList()\n#8 /home/jiminny/vendor/guzzlehttp/promises/src/Promise.php(69): GuzzleHttp\\\\Promise\\\\Promise->waitIfPending()\n#9 /home/jiminny/vendor/guzzlehttp/guzzle/src/Client.php(189): GuzzleHttp\\\\Promise\\\\Promise->wait()\n#10 /home/jiminny/vendor/hubspot/hubspot-php/src/Http/Client.php(113): GuzzleHttp\\\\Client->request('POST', 'https://api.hub...', Array)\n#11 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(163): SevenShores\\\\Hubspot\\\\Http\\\\Client->request('POST', 'https://api.hub...', Array)\n#12 /home/jiminny/app/Services/Crm/Hubspot/Pagination/HubspotPaginationService.php(51): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->executeSearchRequest(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), 'https://api.hub...', Array, Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\PaginationState))\n#13 /home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Pagination\\\\HubspotPaginationService->getPaginatedDataGenerator(Object(Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client), Array, 'contact', 0, 0, NULL)\n#14 /home/jiminny/app/Services/Crm/Hubspot/Client.php(175): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedDataGenerator(Array, 'contact', 0, 0, NULL)\n#15 /home/jiminny/app/Services/Crm/Hubspot/Service.php(1203): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getPaginatedData(Array, 'contact')\n#16 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(353): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->matchByName('Robot')\n#17 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->rateLimit()\n#18 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand->handle(Object(Jiminny\\\\Jobs\\\\JobDispatcher), Object(Jiminny\\\\Services\\\\Kiosk\\\\AutomatedReports\\\\AutomatedReportsService), Object(Jiminny\\\\Repositories\\\\AutomatedReportsRepository), Object(Jiminny\\\\Services\\\\UserPilot\\\\UserPilotClient))\n#19 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\\\Container\\\\BoundMethod::Illuminate\\\\Container\\\\{closure}()\n#20 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\\\\Container\\\\Util::unwrapIfClosure(Object(Closure))\n#21 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\\\Container\\\\BoundMethod::callBoundMethod(Object(Illuminate\\\\Foundation\\\\Application), Array, Object(Closure))\n#22 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\\\\Container\\\\BoundMethod::call(Object(Illuminate\\\\Foundation\\\\Application), Array, Array, NULL)\n#23 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\\\Container\\\\Container->call(Array)\n#24 /home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\\\Console\\\\Command->execute(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#25 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\\\Component\\\\Console\\\\Command\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Illuminate\\\\Console\\\\OutputStyle))\n#26 /home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\\\\Console\\\\Command->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#27 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\\\Component\\\\Console\\\\Application->doRunCommand(Object(Jiminny\\\\Console\\\\Commands\\\\JiminnyDebugCommand), Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#28 /home/jiminny/vendor/symfony/console/Application.php(195): Symfony\\\\Component\\\\Console\\\\Application->doRun(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#29 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\\\Component\\\\Console\\\\Application->run(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#30 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\\\\Foundation\\\\Console\\\\Kernel->handle(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput), Object(Symfony\\\\Component\\\\Console\\\\Output\\\\ConsoleOutput))\n#31 /home/jiminny/artisan(13): Illuminate\\\\Foundation\\\\Application->handleCommand(Object(Symfony\\\\Component\\\\Console\\\\Input\\\\ArgvInput))\n#32 {main}\n\"} {\"correlation_id\":\"a9e2de8b-b538-437e-bbe7-82636da81995\",\"trace_id\":\"e517ae80-e149-490c-b719-309e898b3c93\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fb59e309-d2cc-4fe0-9db2-544112c25477\",\"trace_id\":\"28ccdd4f-bf3a-4545-bc8a-d94188f8204f\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bff14f9f-db1d-4b6c-bd92-ca810b31790a\",\"trace_id\":\"ed08145b-94b8-4585-8e81-0ad478d038dc\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring start {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:16] local.NOTICE: Monitoring end {\"correlation_id\":\"54ed6493-c74e-4491-b2ff-9404528f1525\",\"trace_id\":\"9a1f78c0-6e74-482c-a091-8367df3d0f70\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"7f141a32-060d-4123-bf20-8a8d7abc1482\",\"trace_id\":\"f7fdcb6b-932a-4f6b-ad95-f111628d6cf7\"}\n[2026-05-07 12:58:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:36] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f586fc15-711b-4199-8fdf-dcd2df95af0c\",\"trace_id\":\"828fb459-3b7f-4196-a690-12fc9ce99b1d\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:56:00, 2026-05-07 12:58:00] {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:40] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"01d4e25d-56d5-4c89-bc29-d873e21cc16f\",\"trace_id\":\"ee1fe1ac-362b-47c1-9db2-7915a30cf0f2\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.NOTICE: Calendar sync start {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"924e149e-3462-4043-87da-00838220b970\",\"trace_id\":\"7d0922db-8131-4a52-a0c5-2a7a78df42e8\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:49] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:50] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:51] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:52] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: ef9bb388-453e-4744-a2e1-95e49ced1700 Correlation ID: 3b889c73-f943-4048-ba3b-63ac50581245 Timestamp: 2026-05-07 12:58:53Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:53Z\\\",\\\"trace_id\\\":\\\"ef9bb388-453e-4744-a2e1-95e49ced1700\\\",\\\"correlation_id\\\":\\\"3b889c73-f943-4048-ba3b-63ac50581245\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:53] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 0b8181c0-c858-4d17-af69-c23b7f5a0a00 Correlation ID: 2ce9e931-f423-4048-b1d7-ae1910cd4834 Timestamp: 2026-05-07 12:58:54Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:54Z\\\",\\\"trace_id\\\":\\\"0b8181c0-c858-4d17-af69-c23b7f5a0a00\\\",\\\"correlation_id\\\":\\\"2ce9e931-f423-4048-b1d7-ae1910cd4834\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:54] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:55] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 4f38b1ca-479e-445c-8db5-29366d0a0c00 Correlation ID: d0a4d623-1a23-4fcc-aebf-ccafeed44a92 Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"4f38b1ca-479e-445c-8db5-29366d0a0c00\\\",\\\"correlation_id\\\":\\\"d0a4d623-1a23-4fcc-aebf-ccafeed44a92\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [Calendar] Processing sync {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"from\":null,\"to\":null,\"delta\":\"CIiFh8TP44kDEIiFh8TP44kDGAUgkZvkzgIokZvkzgI=\",\"last_sync\":\"2024-12-09 07:12:53\",\"dateMode\":\"daily\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 1791a948-a974-424b-9246-7fedfa913b00 Correlation ID: b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec Timestamp: 2026-05-07 12:58:56Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:56Z\\\",\\\"trace_id\\\":\\\"1791a948-a974-424b-9246-7fedfa913b00\\\",\\\"correlation_id\\\":\\\"b0e7bf62-d69e-49dd-b7c9-9550f0bd2aec\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:56] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"a33076c1-8d97-431a-99f0-85c9524e118b\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"415d01eb-54ca-4663-adfe-384b7045952d\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"responseBody\":\"{\\\"error\\\":\\\"invalid_client\\\",\\\"error_description\\\":\\\"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app 'bbcbb2ef-6200-4fae-82bd-d81f5dd738da'. Trace ID: 2be27598-8820-475c-b6ca-a30513720c00 Correlation ID: d3ed2a98-4aa9-4a63-819b-d36fd20b8d62 Timestamp: 2026-05-07 12:58:57Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:58:57Z\\\",\\\"trace_id\\\":\\\"2be27598-8820-475c-b6ca-a30513720c00\\\",\\\"correlation_id\\\":\\\"d3ed2a98-4aa9-4a63-819b-d36fd20b8d62\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:57] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:58] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"54027c3b-4bdf-435b-9414-9b8b7cd9633f\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"from\":null,\"to\":null,\"delta\":\"CJ_x49O3jpIDEJ_x49O3jpIDGAUgw67KlwMow67KlwM=\",\"last_sync\":\"2026-01-19 07:48:40\",\"dateMode\":\"daily\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Pipedrive] Account not connected for user {\"userId\":\"e6538737-e7b4-455f-a37a-3e79b665a220\",\"account\":{\"Jiminny\\\\Models\\\\SocialAccount\":{\"id\":1116,\"sociable_id\":241,\"provider_user_id\":\"19555731\",\"expires\":1775683749,\"refresh_token_expires\":null,\"provider\":\"pipedrive\",\"state\":\"full-refresh\",\"auth_scope\":\"base,deals:full,activities:full,contacts:full,search:read\",\"retry_after\":null,\"created_at\":\"2023-09-08 09:44:29\",\"updated_at\":\"2026-04-08 22:58:34\"}}} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] CRM disconnected for user so events will not be matched {\"provider\":\"pipedrive\",\"user_id\":241,\"message\":\"Your Pipedrive account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Google Calendar] Failed to watch channel for calendar {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.WARNING: [Calendar] Sync failed {\"calendarId\":\"2676cb6d-f86c-427e-bf78-591e388e3c1e\",\"code\":400,\"reason\":\"{\n \\\"error\\\": {\n \\\"errors\\\": [\n {\n \\\"domain\\\": \\\"global\\\",\n \\\"reason\\\": \\\"push.webhookUrlNotHttps\\\",\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n ],\n \\\"code\\\": 400,\n \\\"message\\\": \\\"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\\\"\n }\n}\"} {\"correlation_id\":\"bd5351f8-4f39-4199-98f5-aa39a1b90962\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [Calendar] Processing sync {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\",\"from\":null,\"to\":null,\"delta\":\"R0usmcdvmMuZCBYV0hguCHhwR3crxfEuMI8zGlf-bMYpCFtdxXvSJWTlnqQvu_jjoOrOYL2VG9rZwFHCERHxGfGEK3CmQX6x8MJG3ZbBXGuVIS6C7u-doY5maMRdsfnrHIAEMJd4Bs_WMfMH4tDJ8j9aul7DHDEJaP7w0PoPPpcoxu4nEk4vk-MolJBEgkSrayEewuBs5JVItUX9lUY2tA.yO2roNQ4Vdm6hBgoutuphGchuzbvsk7aqt5wHfcyeFQ\",\"last_sync\":\"2026-05-06 15:58:35\",\"dateMode\":\"daily\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:58:59] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"b382839b-ba3d-4d03-ab01-70b4f861ddc1\",\"trace_id\":\"9fcbd6a2-9d29-44c4-ba3f-4f06ce898d62\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cb5f9d32-02db-4883-a5c9-a5b86c1a2fbb\",\"trace_id\":\"4fb8a9a0-53b1-414a-813d-a259b89f3203\"}\n[2026-05-07 12:59:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64313a2b-3a92-4419-ae59-caabfc9e9731\",\"trace_id\":\"16443bac-2196-4257-88bc-59445729f276\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring start {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:11] local.NOTICE: Monitoring end {\"correlation_id\":\"7678c2ca-049f-44e4-acce-2e711f8d7d40\",\"trace_id\":\"54ef3d3c-f1ea-4a01-aed2-db19a6739a06\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"44d7c1a1-dfc9-4401-9f63-ad8b5bff9942\",\"trace_id\":\"9f6f5f38-60f5-4869-bfd2-f366d52eaa00\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 12:59:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"f90f3b8c-5161-4963-a963-a40284567af1\",\"trace_id\":\"94731c50-8ce2-44ec-ace6-2d46fb00fdb1\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6f98d5e3-0aa8-496e-853a-a77b7a8b74ec\",\"trace_id\":\"b63e8546-4347-49f0-ad1a-92f4e4504843\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"50260ccd-f119-47b0-baee-514de27801f2\",\"trace_id\":\"40e651df-62f6-4c3a-83ab-842112ec3ece\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring start {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:17] local.NOTICE: Monitoring end {\"correlation_id\":\"f6104856-aca3-4e7b-964e-bba66d730eb3\",\"trace_id\":\"98f34b7b-f715-49cb-8d3a-4e74c1118445\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b4a9e9a2-968c-429b-8fa8-67dd59bb297f\",\"trace_id\":\"ed6a83d0-8edb-4392-8717-26d91ffde80b\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b11474b2-8b19-4a2f-89c3-621fde9d3b1f\",\"trace_id\":\"8018d825-0809-411b-9b2a-078e2da6bacb\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:58:00, 2026-05-07 13:00:00] {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"d3b79f58-f9c8-4063-ac7e-7a0445cd1111\",\"trace_id\":\"802cf505-95fb-4f92-8c1b-79aa3ac53084\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"32bad9c1-861c-4a46-bece-585cc1170bfd\",\"trace_id\":\"0c20e20f-6a91-4346-9455-5cd1451c32a1\"}\n[2026-05-07 13:00:29] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:text-relay:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c9d4f687-1643-431e-9377-2573a2e593fd\",\"trace_id\":\"02fab433-9c9a-49f7-b836-2b8a42551912\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:33] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-notification\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"57870bb4-45e8-47d8-b192-21d3297d2208\",\"trace_id\":\"ba8e9eac-2dc9-4ed8-bbf1-4a35aedb9efb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:55:00] {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:35] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6aeb181b-8314-4d45-aff7-e378793b04d9\",\"trace_id\":\"8ffc66f1-af64-4a58-8ce8-481b3a299dbb\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:55\",\"to\":\"13:00\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:50\",\"to\":\"02:55\"} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:37] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"888d4f67-ad14-4457-b51d-2cf8b2d315f9\",\"trace_id\":\"eaf4b0b3-0414-4563-b227-ce9c6a2e5b7e\"}\n[2026-05-07 13:00:39] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.ERROR: Failed to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:39] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.ERROR: Failed to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\",\"reason\":\"missing or invalid refresh token\",\"previous\":\"\"} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:40] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"c7b4a8f4-7f10-401b-8d76-be978e462783\",\"trace_id\":\"42a77369-3041-4c40-ba73-331193e6c43e\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b619cc55-b4ef-4913-ab44-6bce51933f7e\",\"trace_id\":\"7cacb418-6e9c-410b-bf3a-15bdf1837908\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T13:02:45.724437Z\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:45] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:pre-meeting-reminder\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a765990f-ffe2-44e0-967f-816f5452ce69\",\"trace_id\":\"9aee0f3f-7668-455f-b207-181b58848478\"}\n[2026-05-07 13:00:45] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:49] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"055b4798-a759-4621-9e0b-652f8ee69ea1\",\"trace_id\":\"10911ef4-48d1-404a-9345-ecf0f5cb9977\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:51] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812331,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812332,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812333,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812334,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812335,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Dispatching activity sync job {\"import_id\":812336,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:53] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"dd8cdea2-20f7-42a7-a492-f85b6037fbec\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.ALERT: [SyncActivity] Failed {\"import_id\":812331,\"provider\":\"twilio-flex\",\"provider_id\":317,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Social account for Salesforce cannot be found. Please login to Jiminny to connect.\",\"file\":\"/home/jiminny/app/Services/Crm/BaseService.php\",\"line\":646} {\"correlation_id\":\"fb068e24-e135-4914-9973-94f1a0f5dae2\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:55] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:00:56] local.ALERT: [SyncActivity] Failed {\"import_id\":812332,\"provider\":\"xant\",\"provider_id\":161,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"fe9470d4-bc5a-4195-919d-e4908e439f7c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:56] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:fail-stalled\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"441dabbc-0c1f-4d49-871c-08f96adbed01\",\"trace_id\":\"13597461-50ff-4a40-a329-255430126395\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812333,\"provider\":\"apollo\",\"provider_id\":441,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"e3a8ef92-20c7-4698-a07d-1aa2c21ac82c\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.ALERT: [SyncActivity] Failed {\"import_id\":812334,\"provider\":\"groove\",\"provider_id\":228,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"1a0b64ee-3927-48e6-8ae3-fda14f35babb\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:57] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.ALERT: [SyncActivity] Failed {\"import_id\":812335,\"provider\":\"twilio-video\",\"provider_id\":243,\"team\":\"jiminny\",\"team_id\":1,\"reason\":\"Activity Provider account not connected.\",\"file\":\"/home/jiminny/app/Services/Activity/ActivityProviderService.php\",\"line\":174} {\"correlation_id\":\"5e6fecb1-9905-4ab2-a494-e6d8215430c0\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Start {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:44:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] End {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:58] local.INFO: [SyncActivity] Memory usage {\"import_id\":812336,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27230632,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"f6b9723f-8cbd-4ddc-8b89-9a346abe1f64\",\"trace_id\":\"2fa600c9-120a-4c94-82da-0530a90fc96c\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:00:59] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:transcription:retry-stuck\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"1db560c5-5d8c-419a-bfb0-e761473ecf44\",\"trace_id\":\"79eb494e-fd21-4171-b59d-d7d47358f1fb\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"73c0e9d6-7ef5-4040-8e35-0a9bb4028abf\",\"trace_id\":\"55b51c26-06b9-4b59-b444-53017b805b30\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5a7e717c-f314-4601-b1b8-fd550703f463\",\"trace_id\":\"a64281e5-027f-4856-a3e3-4f176c58eb6e\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"0c425954-2696-4890-97b7-219ccc38cf46\",\"trace_id\":\"d609b364-f3b6-4b85-babb-67caf96efdb1\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:11] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"a6bad97b-3db2-4dd6-839f-fcd485f06e65\",\"trace_id\":\"dcdde4a9-962c-46d1-9386-42adb54efbbf\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"2893478e-8c43-4719-a2e8-7c9c0e0783e9\",\"trace_id\":\"3fc8f1f0-0727-42f1-8ee6-f2b32bd8834b\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Dispatching activity sync job {\"import_id\":812337,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"64f52ca1-b54e-46da-a760-73dbdf407eaf\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3c44e0a7-ec5d-4206-a925-69f6e0783c2a\",\"trace_id\":\"60cf7a36-37ca-4ac4-a632-f317578d908f\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [SyncActivity] Start {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:19] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:00:00\",\"to\":\"2026-05-07 13:00:00\"} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] End {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:20] local.INFO: [SyncActivity] Memory usage {\"import_id\":812337,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":27392888,\"memory_real_usage\":67108864,\"pid\":37116} {\"correlation_id\":\"c17440cb-9db0-403b-a1ad-a1c7e45b75b3\",\"trace_id\":\"2d0db8fa-83be-4207-bfb6-099456ac234e\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"55ebbc10-80bf-4724-ac64-678f6ef891cc\",\"trace_id\":\"f5392dc4-b352-4cae-b82a-004f77bbaf26\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"jiminny:playlists:normalize-sort\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"9e29cfb5-b7fc-41bc-a9fd-a160d2253806\",\"trace_id\":\"3e180d83-299d-4c6c-bdda-d5a8ac156efc\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Service ending {\"runtime_seconds\":56,\"total_cycles\":5,\"files_downloaded\":0,\"empty_files\":0,\"other_portal_skipped\":0,\"total_events\":0,\"events_per_file\":0,\"avg_api_ms\":181.3,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:01:41] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"5a8651dd-d434-467b-931e-1eda429d2b65\",\"trace_id\":\"4c1d2061-cc57-4b72-996d-389270f3539c\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:05] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"fe3480ce-754b-4304-b661-e4ac7234a778\",\"trace_id\":\"619e9c15-f95f-47ce-af85-6d78a6698327\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:07] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"aa98bf14-5737-4097-9f53-ac6833fb7983\",\"trace_id\":\"2f858b11-1073-43d4-996a-57e259ec2795\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring start {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:08] local.NOTICE: Monitoring end {\"correlation_id\":\"25c588be-ddd6-41f1-8db8-ae28f3dd5bf5\",\"trace_id\":\"58b4c110-21ab-4c22-be4f-5be3534cd17d\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:10] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"5e453d7a-4daf-4001-b100-6aa9485d0353\",\"trace_id\":\"d97e1107-3696-4acf-95db-9cc7f37412e1\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:12] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"3fab4dfb-f0ae-4c2c-a882-e09a1ad3ee9b\",\"trace_id\":\"3a66f9c4-3f01-40e2-aee2-e77fdabe793f\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 13:00:00, 2026-05-07 13:02:00] {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:15] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"63252e6d-894f-4cb9-818a-0034bf3545cb\",\"trace_id\":\"7ddf2e72-9174-4623-a622-1a5c9ee952c5\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"cf65b2c4-c602-432d-8087-d0c0fb7f8e80\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"c481124d-04ae-43fb-b1d3-a4282f7af7ff\",\"trace_id\":\"d2d083d1-7cee-4d21-b80e-4485361d9969\"}\n[2026-05-07 13:02:20] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"3e2ef780-0c9d-4c30-9dc9-92315055c632\",\"trace_id\":\"b7b39317-045c-4475-879e-3d399e23fc3e\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"meeting-bot:schedule-bot\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"8cb6c7bf-4a2d-4960-bf8f-0368643fec27\",\"trace_id\":\"68c67cd4-9b92-4e41-bc1e-ebb282ea5211\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:08] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"b18dc815-6c91-43df-b083-125316724586\",\"trace_id\":\"62a636e8-4128-49eb-b99b-15efcfb37267\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring start {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:10] local.NOTICE: Monitoring end {\"correlation_id\":\"d74c3e14-fd1a-4cab-9892-e9e924af1144\",\"trace_id\":\"29547049-25f5-4b62-a603-276e1de3dde8\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:13] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:skip-lists:refresh\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"bd7a8c2f-3f0b-48e9-86c2-0f01f2cfd9e8\",\"trace_id\":\"a3d1ecb5-4122-43c1-98ca-5d74c3dc989c\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"4b20eb61-2970-4a63-8ee0-b392f7406a78\",\"trace_id\":\"892c9d93-c280-4b3f-a97a-bf1266f5c090\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}\n[2026-05-07 13:03:18] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage for command {\"command\":\"mailbox:batch:retry-failed\",\"memoryBeforeCommandInMb\":62.0,\"memoryAfterCommandInMB\":62.0,\"memoryPeakBeforeCommandInMb\":99.727,\"memoryPeakAfterCommandInMB\":99.727} {\"correlation_id\":\"6a165ea3-f101-4ac9-bfcc-e7ad618ac645\",\"trace_id\":\"383367e5-a337-4793-be1c-a88a2a6fa2e5\"}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.3487367,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"bounds":{"left":0.3587101,"top":0.2490024,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.37101063,"top":0.2490024,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.3806516,"top":0.24740623,"width":0.00731383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.3879654,"top":0.24740623,"width":0.006981383,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse HubSpot\\Client\\Crm\\Deals\\ApiException as DealApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\ApiException as ContactApiException;\nuse HubSpot\\Client\\Crm\\Companies\\ApiException as CompanyApiException;\nuse HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectWithAssociations as ContactsWithAssociations;\nuse HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectWithAssociations as CompaniesWithAssociations;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectWithAssociations as DealWithAssociations;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectInput;\nuse HubSpot\\Client\\Crm\\Objects\\Model\\SimplePublicObjectWithAssociations as ObjectWithAssociations;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\Error;\nuse HubSpot\\Client\\Crm\\Pipelines\\Model\\PipelineStage;\nuse HubSpot\\Client\\Crm\\Properties\\Model\\Property;\nuse HubSpot\\Discovery\\Discovery;\nuse Jiminny\\Component\\Utility\\Service\\ProviderRateLimiter;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\RateLimitException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Services\\Crm\\BaseClient;\nuse Jiminny\\Services\\Crm\\Hubspot\\DTO\\Response\\Owner;\nuse Jiminny\\Services\\SocialAccountService;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse SevenShores\\Hubspot\\Exceptions\\HubspotException;\nuse SevenShores\\Hubspot\\Factory;\nuse SevenShores\\Hubspot\\Http\\Response;\nuse Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPaginationService;\nuse Throwable;\n\n/**\n * @phpstan-type CrmFieldOption array{id:string, label:string, value?:string}\n */\nclass Client extends BaseClient implements HubspotClientInterface\n{\n public const string MIN_API_VERSION = '2';\n\n public const string BASE_URL = 'https://api.hubapi.com';\n\n public const int ASSOCIATIONS_BATCH_SIZE_LIMIT = 1000;\n\n private HubspotPaginationService $paginationService;\n private HubspotTokenManager $tokenManager;\n private ProviderRateLimiter $rateLimiter;\n\n public function __construct(\n SocialAccountService $socialAccountService,\n HubspotPaginationService $paginationService,\n HubspotTokenManager $tokenManager,\n ProviderRateLimiter $rateLimiter,\n ) {\n parent::__construct($socialAccountService);\n $this->paginationService = $paginationService;\n $this->tokenManager = $tokenManager;\n $this->rateLimiter = $rateLimiter;\n\n $this->setBaseUrl(self::BASE_URL);\n $this->setVersion(self::MIN_API_VERSION);\n }\n\n /**\n * Single entry point for every HubSpot API call. Enforces the per-portal\n * rate limit configured in the rate_limits table (morphed to the current\n * Configuration) and reacts to a real 429 from HubSpot by translating it\n * into a RateLimitException carrying Retry-After.\n *\n * Wrap any outbound HubSpot call (SDK or raw HTTP) like:\n *\n * $this->executeRequest(fn () => $this->getNewInstance()->crm()->...);\n *\n * @template T\n * @param callable(): T $apiCall\n * @return T\n *\n * @throws RateLimitException\n */\n private function executeRequest(callable $apiCall)\n {\n if (! $this->rateLimiter->canMakeRequest($this->config)) {\n $retryAfter = $this->rateLimiter->requestAvailableIn($this->config);\n\n $this->log->warning('[Hubspot] Rate limit exceeded, deferring request', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n ]);\n\n throw new RateLimitException(\n 'Hubspot rate limit reached for configuration ' . $this->config->getId(),\n $retryAfter,\n );\n }\n\n $this->rateLimiter->incrementRequestCount($this->config);\n\n try {\n return $apiCall();\n } catch (Throwable $e) {\n if ($this->isHubspotRateLimit($e)) {\n $retryAfter = $this->parseRetryAfter($e);\n\n $this->log->warning('[Hubspot] Received 429 from API', [\n 'team_id' => $this->config->team_id,\n 'config_id' => $this->config->getId(),\n 'retry_after' => $retryAfter,\n 'reason' => $e->getMessage(),\n ]);\n\n throw new RateLimitException('Hubspot returned 429', $retryAfter, $e);\n }\n\n throw $e;\n }\n }\n\n public function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n public function parseRetryAfter(Throwable $e): int\n {\n if (method_exists($e, 'getResponseHeaders')) {\n $headers = $e->getResponseHeaders() ?: [];\n $value = $headers['Retry-After'] ?? $headers['retry-after'] ?? null;\n if (is_array($value)) {\n $value = $value[0] ?? null;\n }\n if (is_numeric($value)) {\n return (int) $value;\n }\n }\n\n return 10;\n }\n\n public function getMinimumApiVersion(): string\n {\n return self::MIN_API_VERSION;\n }\n\n public function getInstance(): Factory\n {\n return new Factory([\n 'key' => $this->accessToken,\n 'oauth2' => true,\n 'base_url' => $this->baseUrl,\n ]);\n }\n\n public function getNewInstance(): Discovery\n {\n return \\HubSpot\\Factory::createWithAccessToken($this->accessToken);\n }\n\n /**\n * Secondly and daily limits for Hubspot API\n *\n * Product Tier: Free & Starter | Professional & Enterprise | API add-on (any tier)\n * Burst: 100/10 seconds | 150/10 seconds | 200/10 seconds\n * Daily: 250,000 | 500,000 | 1,000,000\n *\n * Official documentation states: The search endpoints are rate limited to five requests per second.\n * Since with 5 RPS were still hitting secondly rate limits we lowered it to 4\n */\n public function getPaginatedData(array $payload, string $type, int $offset = 0): array\n {\n $total = 0;\n $lastId = null;\n $rows = [];\n foreach ($this->getPaginatedDataGenerator($payload, $type, $offset, $total, $lastId) as $row) {\n $rows[] = $row;\n }\n\n return ['results' => $rows, 'total' => $total, 'last_record' => $lastId];\n }\n\n /**\n * @throws HubspotException\n * @throws SocialAccountTokenInvalidException\n * @throws BadRequest\n */\n public function getPaginatedDataGenerator(\n array $payload,\n string $type,\n int $offset = 0,\n int &$total = 0,\n ?string &$lastRecordId = null\n ): \\Generator {\n return $this->paginationService->getPaginatedDataGenerator(\n $this,\n $payload,\n $type,\n $offset,\n $total,\n $lastRecordId\n );\n }\n\n /**\n * @throws DealApiException\n * @throws CrmException\n */\n public function getOpportunityById(string $crmId, array $fields): array\n {\n try {\n// $deal = $this->executeRequest(fn () => $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $deal = $this->getNewInstance()->crm()->deals()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n 'companies,contacts'\n );\n } catch (DealApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $deal instanceof DealWithAssociations) {\n throw new CrmException('Deal not found');\n }\n\n return [\n 'id' => $deal->getId(),\n 'properties' => $deal->getProperties(),\n 'associations' => $deal->getAssociations(),\n ];\n }\n\n /**\n * Generic batch read method for HubSpot objects\n *\n * @param string $objectType The object type ('deals', 'companies', 'contacts')\n * @param array<string> $crmIds Array of HubSpot object IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with object data\n */\n private function batchReadObjects(string $objectType, array $crmIds, array $fields): array\n {\n if (empty($crmIds)) {\n return [];\n }\n\n $this->validateBatchSize($objectType, $crmIds);\n $this->ensureValidToken();\n\n try {\n $batchConfig = $this->createBatchConfiguration($objectType);\n $batchReadRequest = $this->prepareBatchRequest($batchConfig, $crmIds, $fields);\n $response = $batchConfig['api']->read($batchReadRequest);\n\n $this->validateApiResponse($response, $objectType);\n\n $results = $this->processApiResults($response);\n $this->logBatchResults($objectType, $crmIds, $results);\n\n return $results;\n } catch (\\Throwable $e) {\n $this->handleBatchError($e, $objectType, $crmIds);\n }\n }\n\n private function validateBatchSize(string $objectType, array $crmIds): void\n {\n if (count($crmIds) > 100) {\n throw new \\InvalidArgumentException(\"Batch size cannot exceed 100 {$objectType}\");\n }\n }\n\n private function createBatchConfiguration(string $objectType): array\n {\n $configurations = [\n 'deals' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Deals\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Deals\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->deals()->batchApi(),\n ],\n 'companies' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Companies\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Companies\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->companies()->batchApi(),\n ],\n 'contacts' => [\n 'batchReadRequest' => new \\HubSpot\\Client\\Crm\\Contacts\\Model\\BatchReadInputSimplePublicObjectId(),\n 'inputClass' => \\HubSpot\\Client\\Crm\\Contacts\\Model\\SimplePublicObjectId::class,\n 'api' => $this->getNewInstance()->crm()->contacts()->batchApi(),\n ],\n ];\n\n if (! isset($configurations[$objectType])) {\n throw new \\InvalidArgumentException(\"Unsupported object type: {$objectType}\");\n }\n\n return $configurations[$objectType];\n }\n\n private function prepareBatchRequest(array $batchConfig, array $crmIds, array $fields): object\n {\n $batchReadRequest = $batchConfig['batchReadRequest'];\n $inputClass = $batchConfig['inputClass'];\n\n $inputs = array_map(function ($crmId) use ($inputClass) {\n $input = new $inputClass();\n $input->setId($crmId);\n\n return $input;\n }, $crmIds);\n\n $batchReadRequest->setInputs($inputs);\n $batchReadRequest->setProperties($fields);\n\n return $batchReadRequest;\n }\n\n private function validateApiResponse($response, string $objectType): void\n {\n if (! $response) {\n throw new CrmException(\"HubSpot API returned null response for {$objectType} batch read\");\n }\n }\n\n private function processApiResults($response): array\n {\n $results = [];\n $responseResults = $response->getResults();\n\n if ($responseResults) {\n foreach ($responseResults as $object) {\n if ($object && $object->getId()) {\n $results[$object->getId()] = [\n 'id' => $object->getId(),\n 'properties' => $object->getProperties() ?: [],\n ];\n }\n }\n }\n\n return $results;\n }\n\n private function logBatchResults(string $objectType, array $crmIds, array $results): void\n {\n $this->log->info(\"[HubSpot] Batch fetched {$objectType}\", [\n 'requested_count' => count($crmIds),\n 'returned_count' => count($results),\n 'crm_ids' => $crmIds,\n ]);\n }\n\n private function handleBatchError(\\Throwable $e, string $objectType, array $crmIds): void\n {\n $errorMessage = $e->getMessage() ?: 'Unknown error';\n $errorTrace = $e->getTraceAsString() ?: 'No trace available';\n\n $this->log->error(\"[HubSpot] Failed to batch fetch {$objectType}\", [\n 'crm_ids' => $crmIds,\n 'error' => $errorMessage,\n 'trace' => $errorTrace,\n ]);\n\n throw new CrmException(\"Failed to batch fetch {$objectType}: \" . $errorMessage);\n }\n\n /**\n * Batch read multiple opportunities by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot deal IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with opportunity data\n */\n public function getOpportunitiesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('deals', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple companies by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot company IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with company data\n */\n public function getCompaniesByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('companies', $crmIds, $fields);\n }\n\n /**\n * Batch read multiple contacts by their CRM IDs\n *\n * @param array<string> $crmIds Array of HubSpot contact IDs (max 100)\n * @param array<string> $fields Array of property names to fetch\n *\n * @return array<string, array> Array keyed by CRM ID with contact data\n */\n public function getContactsByIds(array $crmIds, array $fields): array\n {\n return $this->batchReadObjects('contacts', $crmIds, $fields);\n }\n\n /**\n * @throws CompanyApiException\n * @throws CrmException\n */\n public function getAccountById(string $crmId, array $fields): array\n {\n try {\n $company = $this->getNewInstance()->crm()->companies()->basicApi()->getById(\n $crmId,\n implode(',', $fields),\n );\n } catch (CompanyApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch account', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $company instanceof CompaniesWithAssociations) {\n throw new CrmException('Account not found');\n }\n\n return [\n 'id' => $company->getId(),\n 'properties' => $company->getProperties(),\n ];\n }\n\n /**\n * @throws ContactApiException\n * @throws CrmException\n */\n public function getContactById(string $crmId, array $fields): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $crmId,\n implode(',', $fields)\n );\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'crm_id' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n if (! $contact instanceof ContactsWithAssociations) {\n throw new CrmException('Contact not found');\n }\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n }\n\n /**\n * This is email search request that Hubspot offers as GET (more generous quota)\n */\n public function getContactByEmail(string $email, array $fields = []): array\n {\n try {\n $contact = $this->getNewInstance()->crm()->contacts()->basicApi()->getById(\n $email,\n implode(',', $fields),\n null,\n false,\n 'email'\n );\n\n return [\n 'id' => $contact->getId(),\n 'properties' => $contact->getProperties(),\n ];\n } catch (ContactApiException $e) {\n $this->log->info('[Hubspot] Failed to fetch contact', [\n 'email' => $email,\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n }\n\n /**\n * @throws CrmException\n */\n public function fetchProperty(string $objectType, string $propertyId): Property\n {\n $result = $this->getNewInstance()->crm()->properties()->coreApi()->getByName($objectType, $propertyId);\n\n if (! $result instanceof Property) {\n $this->log->error('[Hubspot] Failed to fetch property', [\n 'object_type' => $objectType,\n 'property_id' => $propertyId,\n 'reason' => $result->getMessage(),\n ]);\n\n throw new CrmException('Failed to fetch property');\n }\n\n return $result;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchPropertyOptions(string $objectType, string $propertyId): array\n {\n /** @var array<CrmFieldOption> */\n return $this->fetchProperty($objectType, $propertyId)->getOptions();\n }\n\n /**\n * @return array<array{id:string, label:string, deleted:bool}>\n */\n public function fetchCallDispositions(): array\n {\n /** @var Response $response */\n $response = $this->getInstance()->engagements()->getCallDispositions();\n\n /**\n * @var array<array{\n * id:string,\n * label:string,\n * deleted: bool\n * }>\n */\n return $response->toArray();\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityPipelineStages(): array\n {\n $stages = [];\n $apiResponse = $this->getNewInstance()->crm()->pipelines()->pipelinesApi()->getAll('deals');\n\n if ($apiResponse instanceof Error) {\n $this->log->error('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $apiResponse->getMessage(),\n ]);\n\n return [];\n }\n\n foreach ($apiResponse->getResults() as $pipeline) {\n $pipelineStages = array_map(\n static function (PipelineStage $stage) {\n return [\n 'id' => $stage->getId(),\n 'label' => $stage->getLabel(),\n ];\n },\n $pipeline->getStages()\n );\n\n $stages = array_merge($stages, $pipelineStages);\n }\n\n return $stages;\n }\n\n public function fetchOpportunityPipelines(): array\n {\n $pipelines = [];\n\n try {\n $apiResponse = $this->makeRequest('/crm/v3/pipelines/deals');\n } catch (\\Exception $e) {\n $this->log->info('[Hubspot] Failed to fetch opportunity pipelines', [\n 'reason' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n $response = $apiResponse->toArray();\n\n foreach ($response['results'] as $pipeline) {\n $pipelines[] = [\n 'id' => $pipeline['id'],\n 'label' => $pipeline['label'],\n ];\n }\n\n return $pipelines;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchMeetingOutcomeFieldOptions(Field $field): array\n {\n return $field->getCrmProviderId() === 'meetingOutcome'\n ? $this->fetchMeetingOutcomeTypes()\n : $this->fetchCallActivityTypes();\n }\n\n public function fetchMeetingOutcomeTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/meeting/hs_meeting_outcome'\n );\n }\n\n public function fetchCallActivityTypes(): array\n {\n return $this->extractMeetingTypeOptions(\n 'https://api.hubapi.com/crm/v3/properties/call/hs_activity_type'\n );\n }\n\n private function extractMeetingTypeOptions(string $endpoint): array\n {\n /** @var Response $response */\n $response = $this->getInstance()\n ->getClient()\n ->request('GET', $endpoint);\n\n /**\n * @var array<array{\n * value: string,\n * label: string,\n * displayOrder: int\n * }> $optionData\n */\n $optionData = $response->toArray()['options'] ?? [];\n\n $options = [];\n foreach ($optionData as $item) {\n $options[] = [\n 'id' => $item['value'],\n 'value' => $item['value'],\n 'label' => $item['label'],\n 'display_order' => $item['displayOrder'],\n ];\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchDispositionFieldOptions(): array\n {\n $options = [];\n\n $dispositions = $this->fetchCallDispositions();\n\n foreach ($dispositions as $disposition) {\n if ($disposition['deleted'] !== false) {\n continue;\n }\n\n $option['value'] = $disposition['id'];\n $option['id'] = $disposition['id'];\n $option['label'] = $disposition['label'];\n\n $options[] = $option;\n }\n\n return $options;\n }\n\n /**\n * @return array<CrmFieldOption>\n */\n public function fetchOpportunityFieldOptions(Field $field): array\n {\n if ($field->isStageField()) {\n return $this->fetchOpportunityPipelineStages();\n }\n\n if ($field->isPipelineField()) {\n return $this->fetchOpportunityPipelines();\n }\n\n return $this->fetchPropertyOptions('deals', $field->getCrmProviderId());\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function makeRequest(string $endpoint, $method = 'GET', $payload = [], ?string $queryString = null)\n {\n $endpoint = self::BASE_URL . $endpoint;\n\n if ($method === 'GET') {\n $response = $this->getInstance()->getClient()?->request(\n method: $method,\n endpoint: $endpoint,\n query_string: $queryString\n );\n } else {\n $response = $this->getInstance()->getClient()->request($method, $endpoint, [\n 'json' => ($payload),\n ]);\n }\n\n $max = $response->getHeaderLine('X-HubSpot-RateLimit-Max'); // \"110\"\n $remaining = $response->getHeaderLine('X-HubSpot-RateLimit-Remaining'); // \"109\"\n $interval = $response->getHeaderLine('X-HubSpot-RateLimit-Interval-Milliseconds'); // \"10000\"\n $body = json_decode((string) $response->getBody(), true);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$max ' . PHP_EOL . print_r($max, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$remaining ' . PHP_EOL . print_r($remaining, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$interval ' . PHP_EOL . print_r($interval, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$body ' . PHP_EOL . print_r($body, true));\n\n return $response;\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function createMeeting(array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings';\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n /**\n * @throws BadRequest\n * @throws HubspotException\n */\n public function updateMeeting(string $meetingId, array $payload): Response\n {\n $endpoint = '/crm/v3/objects/meetings/' . $meetingId;\n\n return $this->makeRequest($endpoint, 'PATCH', $payload);\n }\n\n /**\n * @throws \\Exception\n */\n public function createNote(\n string $body,\n string $ownerId,\n int $timestamp,\n string $objectId,\n NoteObject $noteObject\n ): ?string {\n try {\n $noteInput = new SimplePublicObjectInput([\n 'properties' => [\n 'hs_note_body' => $body,\n 'hubspot_owner_id' => $ownerId,\n 'hs_timestamp' => $timestamp,\n ],\n ]);\n\n // Create note\n $note = $this->getNewInstance()->crm()->objects()->basicApi()->create('note', $noteInput);\n\n $this->getNewInstance()->crm()->objects()->associationsApi()->create(\n 'note',\n $note->getId(),\n $this->getNoteObject($noteObject),\n $objectId,\n $this->getNoteAssociationType($noteObject),\n );\n\n return $note->getId();\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to create note', [\n 'objectId' => $objectId,\n 'noteObject' => $noteObject->getObjectType(),\n 'reason' => $e->getMessage(),\n ]);\n\n \\Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function updateEngagement(string $objectId, array $engagement, array $metadata): void\n {\n $this->getInstance()->engagements()->update($objectId, $engagement, $metadata);\n }\n\n public function getEngagementData(string $engagementId): array\n {\n $engagement = $this->getInstance()->engagements()->get($engagementId);\n\n return $engagement->toArray();\n }\n\n public function createEngagement(array $engagement, array $associations, array $metadata): Response\n {\n return $this->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n }\n\n public function isUnauthorizedException(\\Exception $e): bool\n {\n // Check for specific HubSpot API exception types first\n if ($e instanceof BadRequest) {\n // BadRequest can contain 401 status codes\n return $e->getCode() === 401;\n }\n\n // Check for HTTP client exceptions with status codes\n if ($e instanceof \\GuzzleHttp\\Exception\\RequestException && $e->hasResponse()) {\n $response = $e->getResponse();\n if ($response !== null) {\n return $response->getStatusCode() === 401;\n }\n }\n\n // Check for Guzzle HTTP exceptions\n if ($e instanceof \\GuzzleHttp\\Exception\\ClientException) {\n return $e->getCode() === 401;\n }\n\n // Fallback to string matching as last resort, but be more specific\n $message = strtolower($e->getMessage());\n\n return str_contains($message, '401 unauthorized') ||\n str_contains($message, 'http 401') ||\n str_contains($message, 'status code 401') ||\n (preg_match('/\\b401\\b/', $message) && str_contains($message, 'unauthorized'));\n }\n\n /**\n * Validates and refreshes the access token if needed before API requests.\n * This ensures long-running processes don't fail due to token expiration.\n *\n * @throws SocialAccountTokenInvalidException\n */\n public function ensureValidToken(): void\n {\n if ($this->oauthAccount === null) {\n return;\n }\n\n $newToken = $this->tokenManager->ensureValidToken($this->oauthAccount);\n if ($newToken !== null) {\n $this->accessToken = $newToken;\n }\n }\n\n public function getConfig()\n {\n return $this->config;\n }\n\n // returns only active (archived=false)\n public function getOwners(): array\n {\n return $this->getNewInstance()->crm()->owners()->getAll();\n }\n\n /**\n * @param bool $archived\n *\n * @return array<Owner>|[]\n */\n public function getOwnersArchived(bool $archived = true): array\n {\n $endpoint = '/crm/v3/owners';\n $queryParams = [\n 'archived' => $archived ? 'true' : 'false',\n ];\n $queryString = http_build_query($queryParams);\n\n $owners = [];\n\n try {\n $response = $this->makeRequest(endpoint: $endpoint, queryString: $queryString);\n $responseData = $response?->toArray();\n\n foreach ($responseData['results'] as $result) {\n try {\n $owners[] = Owner::create($result);\n } catch (Throwable $e) {\n $this->log->error('[HubSpot] Failed to process owner data', [\n 'result' => $result,\n 'error' => $e->getMessage(),\n ]);\n\n continue;\n }\n }\n } catch (Throwable $e) {\n $this->log->error('HubSpot] Failed to fetch owners', [\n 'archived' => $archived,\n 'error' => $e->getMessage(),\n ]);\n\n return [];\n }\n\n return $owners;\n }\n\n public function getMeeting(string $engagementId): ObjectWithAssociations\n {\n return $this->getNewInstance()->crm()->objects()->basicApi()\n ->getById('meeting', $engagementId, null, 'contact,company,deal');\n }\n\n public function deleteEngagement(string $engagementId): void\n {\n $this->getInstance()->engagements()->delete((int) $engagementId);\n }\n\n public function getAssociationsData(array $ids, string $fromObject, string $toObject): array\n {\n $associationData = [];\n $idChunks = array_chunk($ids, self::ASSOCIATIONS_BATCH_SIZE_LIMIT);\n\n foreach ($idChunks as $idChunk) {\n try {\n $batchInput = new \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchInputPublicObjectId();\n $batchInput->setInputs(array_map(function ($id) {\n $publicObjectId = new \\HubSpot\\Client\\Crm\\Associations\\Model\\PublicObjectId();\n $publicObjectId->setId($id);\n\n return $publicObjectId;\n }, $idChunk));\n\n $associatedObjectsData = $this\n ->getNewInstance()\n ->crm()\n ->associations()\n ->batchApi()\n ->read($fromObject, $toObject, $batchInput);\n\n if ($associatedObjectsData instanceof \\HubSpot\\Client\\Crm\\Associations\\Model\\BatchResponsePublicAssociationMulti) {\n foreach ($associatedObjectsData->getResults() as $association) {\n $from = $association->getFrom()->getId();\n $toAssociations = $association->getTo();\n\n if (! empty($toAssociations)) {\n $associationData[$from] = array_map(function ($item) {\n return $item->getId();\n }, $toAssociations);\n }\n }\n }\n } catch (\\Exception $e) {\n $this->log->error('[Hubspot] Failed to fetch associations', [\n 'from_object' => $fromObject,\n 'to_object' => $toObject,\n 'reason' => $e->getMessage(),\n ]);\n }\n }\n\n return $associationData;\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteAssociationType(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'note_to_deal',\n NoteObject::Lead, NoteObject::Contact => 'note_to_contact', // or 'note_to_lead' if your portal supports it\n NoteObject::Account => 'note_to_company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n /**\n * @throws \\Exception\n */\n private function getNoteObject(NoteObject $noteObject): string\n {\n return match($noteObject) {\n NoteObject::Opportunity => 'deal',\n NoteObject::Lead, NoteObject::Contact => 'contact',\n NoteObject::Account => 'company',\n NoteObject::Call, NoteObject::Event => throw new \\Exception('Not supported'),\n };\n }\n\n public function addAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/create\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n\n public function removeAssociations(string $objectType, string $associationType, array $payload): Response\n {\n $endpoint = \"/crm/v4/associations/$objectType/$associationType/batch/archive\";\n\n return $this->makeRequest($endpoint, 'POST', $payload);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
4314526982584152007
|
6701901348398533693
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
Close
Sync Changes
Hide This Notification
Code changed:
Hide
633
Previous Highlighted Error
Next Highlighted Error
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"fa8a3008-d298-4682-bbbc-fdc77520e0d7","trace_id":"7cfb2afb-9fc4-4a77-81be-65dce93c7d80"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"932ced9d-9804-48ed-976a-1f8bf5e75707","trace_id":"21bf320c-58f3-4082-831d-9f07f6c6a669"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:17] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.55,"average_seconds_per_request":0.55} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring start {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.51,"average_seconds_per_request":0.51} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:18] local.NOTICE: Monitoring end {"correlation_id":"ae3ec78f-432c-4e22-b73b-0413af73d9f3","trace_id":"c2feb517-0f2b-4ad9-bce5-4d57476a164b"}
[2026-05-07 12:52:18] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:19] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.49,"average_seconds_per_request":0.49} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2bf2f73f-007c-4909-925e-f1749fbf87b3","trace_id":"8429123c-d92c-48d9-a154-29bc0aa0e2a1"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.48,"average_seconds_per_request":0.48} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:20] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.62,"average_seconds_per_request":0.62} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:21] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.78,"average_seconds_per_request":0.78} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:22] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":1.21,"average_seconds_per_request":1.21} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:23] local.INFO: [Hubspot] Pagination completed {"team_id":2,"endpoint":"https://api.hubapi.com/crm/v3/objects/contact/search","total_requests":1,"total_records_fetched":1,"total_elapsed_seconds":0.53,"average_seconds_per_request":0.53} {"correlation_id":"84c9b84a-9f60-4e35-956a-ead94112d174","trace_id":"07a542c8-266e-40e4-97ec-725d0fd3192d"}
[2026-05-07 12:52:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:25] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d1bc569d-b1ae-4ac5-b2cd-0bb8d765bbd8","trace_id":"64ccac6b-34f7-45ed-a8ac-b63adbb19107"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:50:00, 2026-05-07 12:52:00] {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6e1a36d0-a87a-455f-88b9-04f16718ea33","trace_id":"ce4c48f7-dbeb-4574-9f0a-1097a7c1dc6c"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] STARTING batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: [EmailSchedule] FINISHED batch create {"host":"docker_lamp_1"} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:31] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:create","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"80549428-beea-4a6c-97d3-818ca0f059f3","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:32] local.INFO: [Jiminny\Jobs\Mailbox\CreateBatches] processed 2 inboxes and created 0 batches {"userId":null,"batchSize":30,"maxBatches":1000} {"correlation_id":"92242bd6-7014-4487-a50b-1570e1a88e7a","trace_id":"55ddd59b-073b-4331-8cdb-baa869dcff70"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:52:39] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d467eace-3254-4ecc-8d8e-a94688d6d3ad","trace_id":"5105ca8f-3c0d-4798-b748-5a7d6fbd7531"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"04363b29-2f82-470a-89d0-c5ce4f4779d7","trace_id":"3c76a1f1-3348-4e2b-897c-4a216ca95147"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:11] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5ebbecd0-866c-443f-965f-b6ac03735379","trace_id":"e0a724a5-bb4b-4fe6-9fe9-36ea1c3f0326"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring start {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:18] local.NOTICE: Monitoring end {"correlation_id":"f39f0d3c-a292-41cb-8834-45dae1f8cf47","trace_id":"b6e7e2a7-85af-401d-afc6-bec2bdab34d7"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"419bb747-2669-496f-944b-1073496cc271","trace_id":"4cb913a4-ef75-422b-80eb-fbfb988521ed"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f4805c97-9344-4111-8be2-2b1efeae07bb","trace_id":"cf7ff1ad-3e3d-4a7a-a1a6-99a883cbfe22"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:53:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:retry-failed","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2eadb06b-2c2e-4a7f-8920-77bd30d6cd7f","trace_id":"75f27a23-2021-41a5-9e5f-4b1cb4f143a6"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ad151521-f676-4351-a70b-f44dc0b94990","trace_id":"17e39c4c-85cb-49a4-815e-b7315a8c2249"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"ed0583cf-03c6-4696-b859-876c8efa4473","trace_id":"3f9e0a3c-2178-4885-95eb-8618b8cfc042"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring start {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:10] local.NOTICE: Monitoring end {"correlation_id":"7142250a-b897-4620-8ff7-fd9b3a1f3802","trace_id":"597def1e-ca38-4cc4-8890-fdcd5baff948"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:12] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"cb2ada48-0200-4eb3-a8c5-6cb8ea43ec0d","trace_id":"73937bdc-10b9-4508-9ef2-86420fe774fc"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"8f1d8932-2839-4256-99ab-1fd13e8381c6","trace_id":"cc090767-edc2-4a89-90c2-116f1737de7f"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:52:00, 2026-05-07 12:54:00] {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"9d324c6d-5b36-46ee-89c6-f95f86bf3f39","trace_id":"860cdff0-9356-4e94-84cc-e011a74ba56c"}
[2026-05-07 12:54:18] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1496,"provider":"aircall"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:18] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.ERROR: [Aircall] Re-activating webhooks failed {"team_id":1,"reason":"{\"message\":\"Forbidden\"}"} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:aircall:check-and-renew","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c2009a88-eea6-4954-8642-ef5d9cb56b42","trace_id":"71a5ea6f-c8d8-45e2-8458-a2f572f5fcab"}
[2026-05-07 12:54:21] local.INFO: [RetryFailedDownloads] Starting {"options":{"from":null,"to":null,"help":false,"silent":false,"quiet":false,"verbose":false,"version":false,"ansi":null,"no-interaction":false,"env":null}} {"correlation_id":"825ef2d7-b5f8-45cd-b19d-20a179b06934","trace_id":"5825a6c8-14c9-4bec-b688-d4895cfc41cc"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:05] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c0dc8e25-7a51-4023-be61-d0abd6d72e37","trace_id":"16b8fa3e-92b1-465e-82d4-642a2d14c7c5"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1c65fdd1-1f79-435d-b469-add46ddafd63","trace_id":"62f2a3bb-3be7-4c76-a9dd-222bfb895fab"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring start {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:11] local.NOTICE: Monitoring end {"correlation_id":"f115f9bc-bb59-4fc9-8c9f-8b69baba1a55","trace_id":"e75cb5c6-6dd8-4000-8d26-4418020c7cfe"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"dba5c474-4d40-44da-baf2-f8b30db9a2f5","trace_id":"adb45622-1fb0-457c-bf20-8dcceab2d62a"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:16] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"22c96a8e-4424-4a1f-b349-206276eefe4c","trace_id":"1444d00b-35f8-4eba-b5e6-7c36c9cdeb4c"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5f958e8d-1d01-4144-abd6-2513e5524ad3","trace_id":"828bc5b7-e2aa-4443-901f-38dd94bb7cc5"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:22] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:text-relay:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"6bd1c9cb-cd9a-42a9-87fe-45cb7bac687a","trace_id":"0f2f5d66-c4c9-46a5-a31b-6937663ce1ad"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Running pre-meeting notification command {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-notification","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"c5dd8132-d7e1-4caa-84d1-0a50d02df8da","trace_id":"bc7341c5-b8e2-48ea-9670-7ec375363180"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:45:00, 2026-05-07 12:50:00] {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f44cba2d-7f2e-4fa9-9d6c-c5597fd0c3a0","trace_id":"efb1619f-4185-4319-9bfb-305cee0b6bfc"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:50","to":"12:55"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:45","to":"02:50"} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:28] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"3792b31a-080a-4fe4-9823-5602361325ba","trace_id":"41a2fde1-48f6-4667-84b7-a2f93e9ad2da"}
[2026-05-07 12:55:30] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:30] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.ERROR: Failed to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.ERROR: Failed to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06","reason":"missing or invalid refresh token","previous":""} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"e31362f8-5362-478d-911d-099b61f96cd2","trace_id":"2587b5d0-6bef-40a5-afd5-a15003b7cf95"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"5e676ae4-5d63-49d4-9001-559088adf06b","trace_id":"2fcce073-dd68-4c99-b7c4-b9e03c20b8e4"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:57:40.609671Z"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:40] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:pre-meeting-reminder","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"1f830896-8142-41d1-bfc9-4cbb9179ffda","trace_id":"e348a096-7f37-4308-a6d8-66131e8be901"}
[2026-05-07 12:55:40] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:45] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:46] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:55:51] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:06] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:08] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"meeting-bot:schedule-bot","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2d8b30b4-87aa-480f-9b9e-5a9c709b742a","trace_id":"25b7be6c-1faf-430b-a724-a4ff28773a31"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:10] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"efd336d7-db4d-459e-b6e7-bf73454e955e","trace_id":"0a82c3d5-0417-48c8-b88f-70ec33e2326a"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring start {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:12] local.NOTICE: Monitoring end {"correlation_id":"68481576-8ca6-4ee5-821b-07374702971d","trace_id":"c73eac09-5d20-425f-9c22-bd6c65fc60c9"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:17] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:skip-lists:refresh","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"bd0cdc75-b5c2-4dbb-bc44-e36c96813d24","trace_id":"f688cd98-c171-4e30-8c72-afc14f040861"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"f01636a9-4059-4ab0-9ad2-b078d42cedbd","trace_id":"fea938d8-aedc-40ec-b8c2-2f487e1ac808"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:54:00, 2026-05-07 12:56:00] {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:23] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"conference:monitor:count","memoryBeforeCommandInMb":60.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"d4558901-264d-4238-8589-62a137bac1fd","trace_id":"38e6b5dc-ebd6-46a7-8224-7374d4e58630"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"crm:sync-hubspot-objects","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"7bfaf9be-0ca1-4170-a0c9-83e0ed61881c","trace_id":"ba7f9eee-8dcb-4c94-acb0-18f9363757ad"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:26] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"activity:notify-not-logged","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"2541e0fa-1117-4863-9523-d723b5821a24","trace_id":"d9600320-5133-4938-bdd1-2256dfdf8db4"}
[2026-05-07 12:56:35] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] STARTING Inbox Sync {"host":"docker_lamp_1"} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [EmailSchedule] FINISHED Inbox Sync {"host":"docker_lamp_1","events":2} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"mailbox:sync","memoryBeforeCommandInMb":62.0,"memoryAfterCommandInMB":62.0,"memoryPeakBeforeCommandInMb":99.727,"memoryPeakAfterCommandInMB":99.727} {"correlation_id":"e444f776-37db-4c6d-b30e-20b01a089de7","trace_id":"1168869e-e07c-4702-a046-42fc95a91f6d"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {"expires_in":1800,"cached_for":1500} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {"empty_results":5,"max_empty_results":5} {"correlation_id":"fa65a15d-da5b-4c86-ae85-c16937786996","trace_id":"7e655fe3-04eb-4a0f-b056-eb64e9c75a80"}
[2026-05-07 12:56:37] local.INFO: [HubSpot Journal Polling] Service ending {"runtime_seconds":57,"total_cycles":5,"files_downloaded":0,"empty_files":0,"other_portal_skipped":0,"total_events":0,"events_per_file":0,"avg_api_ms":238.3,"avg_download_ms":0.0,"avg_transform_ms":0.0,"avg_process_ms":0.0,"peak_memory_mb":99.73} {"correlation_id"...
|
4215
|
NULL
|
NULL
|
NULL
|
|
4216
|
151
|
5
|
2026-05-07T13:18:08.631445+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159888631_m1.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Replace Field","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"retry_error","depth":4,"on_screen":true,"value":"retry_error","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match Case","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":3,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Replace History","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Replace","depth":4,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Preserve case","depth":3,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.024444444},"on_screen":false,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"0 results","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Window, Multiple Cursors","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Click to highlight","depth":4,"on_screen":false,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
7003342431495828287
|
-8322363893230748094
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Show Replace Field
Search History
retry_error
New Line
Match Case
Words
Regex
Replace History
Replace
New Line
Preserve case
0 results
Previous Occurrence
Next Occurrence
Filter Search Results
Open in Window, Multiple Cursors
Click to highlight
iTerm2ShellEditViewSessionScriptsProfilesWindowHelpliholLukas/Stefka 121 - in 1h 12 m100% <78Thu 7 May 16:18:10DEV (docker)DOCKERDEV (docker)882APP (-zsh)jiminny-worker-processing-2:j1minny-worker-processing-2_00: startedjiminny-worker-processing-3:jiminny-worker-processing-3_00: startedjiminny-worker-processing-4:jiminny-worker-processing-4_00: startedjiminny-worker-processing-5:jiminny-worker-processing-5_00: startedjiminny-worker-processing-delayed: jiminny-worker-processing-delayed_00: startedworker:worker_00: startedworker-analytics:worker-analytics_00: startedworker-audio:worker-audio_00: startedworker-calendar:worker-calendar_00:startedworker-conferences:worker-conferences_00: startedworker-crm-sync:worker-crm-sync_00: startedworker-crm-update:worker-crm-update_00: startedworker-download:worker-download_00:startedworker-emails:worker-emails_00: startedworker-es-update:worker-es-update_00:startedworker-nudges:worker-nudges_00: startedroot@docker_lamp_1:/home/jiminny# php artisan jiminny:debugMatchingcontact 0-zsh• 84screenpipe*•$5-zsh₴6DEVSevenShores\Hubspot\Exceptions\BadRequestClient error: *POST [URL_WITH_CREDENTIALS] ]...
|
4213
|
NULL
|
NULL
|
NULL
|
|
4215
|
152
|
4
|
2026-05-07T13:18:06.088464+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778159886088_m2.jpg...
|
PhpStorm
|
faVsco.js – Client.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>Some incoming commits are not fetched<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4235983745889776938
|
-8204421443435123770
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
PhostormINavigarecodeFV faVsco.jsProiect© TrackRecordingFileSiz© TrackRecordingSizeEnT. ValidateSmitProspect:AjReports0 CalendarConference(C) Hubspot/Service.phoC) Companies.php(C) MatchActivityermData.pho(C) CrmActivityService.php(C) CachedCrmServiceDecorator.phpTHubspot/..SyncCrmEntitiesTrait.pho©) Pipedrive/Service.php0 Servicelntertace.php@ bullnorn@ OpportunitvSvncTest.oho(C) RateLimit.oho> OJ CloseC Coppercllass Uuient extends Basedlient imoilements Huhsnotu ientinterface>J Crmobiects_ DecorareAcuivily• DummyHelpers114115116v h HubspotAccountSyncStrate>D Actionsn ContactsuncStrate120m Fields• Malournal1 Metadatalv OpportunitySyncSti>MConcerns.124(c) Hubsnotl actMorC HubspotLastMor(C) Hubsnotl actMou(C) Hubsnotl actMou12%(C) Hubsnotl actMo(C) HubsnotSinaleS© HubspotSyncStr© HubspotWebhoc~ M Padination© HubspotPaginat© PaginationConfi(C) PaqinationState.> D ProspectSearchStr:136› D Redisv D ServiceTraits139() OpportunitvSvnc|14€() SvncCrmEntities141 C ›T SuncFieldstirait.() WriteCrmTrait.n146 Gt ›• M UtilsM Webhook155 Gt ›© BatchSyncCollector 159c) RatchSvncRedisSec) Client nhrC) ClocedDea|Stadecs@DealFieldsService.p 163BL B08 X2Anrivate function executeRequest(callable Sanicallalchrow seZ usagespublic function isHubspotRateLimit(Throwable Se): boolmethod: 'qetCode') && (int) Se->qetCode@ === 429:public function parseRetrvAfter(Throwable Se): int1+ method exasts(se.'aetResnonseHeaders'))&sheaders = $e->getResponseHeaders ?: LJ:Svalue = Sheadensl 'Retry-Aften'] 2> Sheadensf 'retry-aften'] 22 null•if Gs arrav(Svalue)) <Svalue = Svaluelol 22 null.if (is_numeric($value)) {netunnint Cvaltte.return 10:public function getMinimumApiVersion0: string{...}public function getInstance@: Factoryf...,public function getNewInstance@: Discoveryf...}secondlu and danlu limits for Hubsoot APT• Product Tier: Free & Starter | Professional & Enterprise | APl add-on (any tier)arQube for INF suadections. Netect more cecurity iccuec in vour DHIfiloc II Trv SonarQube Cloud for fres /I Download SonarQuhe Sorver |l I earn more / Don't ack adain (todav 10-25)4 HS_local jiminny@localhostiti accounts (jiminny@localhost]A console [PKOU.A console [STAGINGI365367371373-382[385E387— 389392393394399400MIII!I|26-05-07 12:57:19 Local.NOTICE: Monitoring start26-05-07 12:57:191 local. NOTICE: Monitoring end• "correlation_1d":"4C2d4775-716d-4Ca6-D94d-CD1 wV633 A V26-05-07 12:57:22) Local.INF0: Jiminny Console \Commands \Command::run Memory usage before starting command ¿"comma26-05-07 12:57:22Jfor command 1"command": "mailbox126-05-07 12:57:25 2ocaL. INF0: Jiminny Console Commands Command::run Memory usage before startina command «"comma26-05-07 12:57:25Jamo 1"- "correlation id".126-05-07 12:57:25 Loc0L. INF0: EmailSchedulel FINISHEd batch orocess "host"*"docker Lamo 1" "orocessed":0r *"co(26-05-07 12:57:25) local.INF0: Jiminny Console\Commands \Command::run Memory usageand t"command": "mailbox126-05-07 12257-22D0cLNSO Jaiminny Consolle kommands Vommande enun Memony usade hefone stantino command "comma26-05-07 12:57:27) local.INF0: [EmailSchedule] STARTING batch create {"host":26-05-07 12:57:27] local.INF0: [EmailSchedule] FINISHED batch create {"host":"docker_lam_1"} {"correlation_id":"1"} &"cornelation id".".26-05-07 12:57:27] local.INF0: Jiminny \Console\Commands\Command::run Memory usagfor command {"command": "mailbox26-05-07 12:57:28] local.INF0: [Jiminny\Jobs \Mailbox\CreateBatches] processed 2 inboxes and created 0 batches {"us26-05-07 12:58:06] local.INF0: [SocialAccountService) Fetching token {"socialAccountId":1499,"provider":"hubspot"])26-05-07 12:58:06] local.INF0: [SocialAccountService) Token retrieved {"socialAccountId":1499,"provider":"hubspot'20-05-01 12.00.00J LocaL.LNrU: Lencryptedlokennanager, benerating access coken. 1"mode. Legacys 1correlation_126-05-07 12:58:06] local.INF0: [Crm0wnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspotZo-Us-01 12.00.00 LocaL.ckKUK. ULlent error.'POST https://api.hubapi.com/crm/v3/obiects/contact/search*resultectatus":"error" "message":"You have reached your secondly limit." "errorType":"RATE LIMIT" "correlationId":"019e02€429): Client error: 'POST https://api.huhome/J1m1nny/vendor/hubspot/nubspot-php/src/exceptions/Hubspottxcept1on.pnp:24Inome/aaminny/vendor/nubspor/nubspor-oho/sccirco/ulnentonous: sevenshoresWuospor exceocions Wunsnorexceni/home/iiminny/app/Services/Crm/Hubspot/Paqination/HubspotPaqinationService.oho(163): SevenShores||Hubspot\\Httpl\(home//iiminny/aop/Services/crm/Hubsoot/Paqination/HubsootPaqinationService.ono/51: Jiminnv ServicesCrmHubso/home/jiminny/app/Services/Crm/Hubspot/Client.php(194): Jiminny\\Services\\Crm\\Hubspot\\Pagination\\HubspotPagin/home//Timinny/aop/Services/crm/Hubsoot/Client.ono/15): JiminnvServicesCrmHubspotCuient->oetPaqinatedData/home/jiminny/apo/Services/Crm/Hubspot/Service.pho(1203): Jiminnv||Services\Crml\Hubspot|\CLient->qetPaqinatedDatJhome/aliminny/laoo//console/.Commands/AaiminnyDebuacommand..oho/05%9lLiminnyServicesViem HubsnotSenvice->matichB/home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny\Console\\Commands|JiminnyDebugCommand->home/~iminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.nhn(36):JiminnvConsoleCommands/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod:home/iiminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.ohn(96)• TlluminateContainenUtilhome /iiminny/vendor/laravel/framework/src/Tlluminate/Container/BoundMethod.ohn(35)• TlluminateContainenBounhome /iiminny/vendor/laravel/framework/soc/Tlluminate/Container/Containen.ohn 799)• TlluminateContainen Round/home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\\Container\\Container/home/jiminny/vendor/symfony/console/Command/Command.php(341): Illuminate\\Console\\Command->execute(0bject(Symfc/home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Comn/home/jiminny/vendor/symfony/console/Application.php(1117): Illuminate\Console\Command->run(Object (Symfony\Con/home/jiminny/vendor/symfony/console/Application.php(356): Symfony\Component)\Console\Application->doRunCommanc/home/jiminny/vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun(0biect/home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Cor/home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\Foundation\(/home/jiminny/artisan(13): Illuminatel(Foundation\Application->handleCommand(Obiect(Symfony)\Componentl\Console){main?eption(code: 429): Client error: 'POST httos://aoi.hu• Lukas sterka 121 • In ih 12mAskJiminnyReportActivityServiceTest vCascadeHubspot Rate LimitingHubspot Rate Limit HHow to Access the Header in Your CodeIt you need to check the header manually tor debugging:"phpFor new SDK (Ap1Except1on)try{Sresponse = Sclient->request(...):} catch (\HubSpot\Client\Crm\Objects\ApiException $e) 1Sheaders = $e->getResponseHeaders() ?: []:SretryAfter = Sheaders 'Retry-Atter'10 ?? Sheaders "retry-after' 0 7? nuut:if (SretryAfter) {sent retry guidancesteeptlanosrethyatcer),I No header - use default hased on error meccadeSbody = ison decode(Se->getResponseBody(), true):SretryAftercvName'] 22 null) {"TEN SELUNDLT_KULLING →> 10,"SECONDLY => 1.default = 10.RecommendationThe current imolementation at Service.pho: 1721-1727 already handles this correctly by checkina policvName :^ oho$response = json_decode($e->getResponseBody(), true);sretryAtter =isset (Sresponse['policvName'] )Sc Sresnonsef'nolicvame'1 ==self.-TEN SECONDLY ROLLING POLTC? self::TEN SECONDLY ROLLING LIMIT# 10 coconde: 1; // Default 1 second for other limitsTo see if headers are actually present, add temporary logging:• php$headers = $e->getResponseHeaders() ?: []:Loa: :debua("[HubSpot) Rate limit response headers'. ['headersi = Cheaderç.'retry after' = Sheaders ['Retry-After'] ?? Sheaders['retry-after'] ?? 'NOT PRESENT'.100% 12Thu 7 May 16:18:06+0 ..Gal .Ask anvthina (&4D< CodeC° AdantiveW Windsurf Teams128.22UTC.8io 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|